diff --git a/.cursor/rules/design.mdc b/.cursor/rules/design.mdc old mode 100644 new mode 100755 diff --git a/.dockerignore b/.dockerignore old mode 100644 new mode 100755 diff --git a/.editorconfig b/.editorconfig old mode 100644 new mode 100755 diff --git a/.env.example b/.env.example old mode 100644 new mode 100755 diff --git a/.gitattributes b/.gitattributes old mode 100644 new mode 100755 diff --git a/.github/dependabot.yml b/.github/dependabot.yml old mode 100644 new mode 100755 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml old mode 100644 new mode 100755 diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/.kamal/hooks/docker-setup.sample b/.kamal/hooks/docker-setup.sample old mode 100644 new mode 100755 diff --git a/.kamal/hooks/post-app-boot.sample b/.kamal/hooks/post-app-boot.sample old mode 100644 new mode 100755 diff --git a/.kamal/hooks/post-deploy.sample b/.kamal/hooks/post-deploy.sample old mode 100644 new mode 100755 diff --git a/.kamal/hooks/post-proxy-reboot.sample b/.kamal/hooks/post-proxy-reboot.sample old mode 100644 new mode 100755 diff --git a/.kamal/hooks/pre-app-boot.sample b/.kamal/hooks/pre-app-boot.sample old mode 100644 new mode 100755 diff --git a/.kamal/hooks/pre-build.sample b/.kamal/hooks/pre-build.sample old mode 100644 new mode 100755 diff --git a/.kamal/hooks/pre-connect.sample b/.kamal/hooks/pre-connect.sample old mode 100644 new mode 100755 diff --git a/.kamal/hooks/pre-deploy.sample b/.kamal/hooks/pre-deploy.sample old mode 100644 new mode 100755 diff --git a/.kamal/hooks/pre-proxy-reboot.sample b/.kamal/hooks/pre-proxy-reboot.sample old mode 100644 new mode 100755 diff --git a/.kamal/secrets b/.kamal/secrets old mode 100644 new mode 100755 diff --git a/.node-version b/.node-version old mode 100644 new mode 100755 diff --git a/.rubocop.yml b/.rubocop.yml old mode 100644 new mode 100755 diff --git a/.ruby-version b/.ruby-version old mode 100644 new mode 100755 diff --git a/.superdesign/design_iterations/default_ui_darkmode.css b/.superdesign/design_iterations/default_ui_darkmode.css old mode 100644 new mode 100755 diff --git a/.superdesign/design_iterations/enhanced_aperonight_components.html b/.superdesign/design_iterations/enhanced_aperonight_components.html old mode 100644 new mode 100755 diff --git a/.superdesign/design_iterations/enhanced_aperonight_home_with_finder.html b/.superdesign/design_iterations/enhanced_aperonight_home_with_finder.html old mode 100644 new mode 100755 diff --git a/.superdesign/design_iterations/enhanced_aperonight_theme.css b/.superdesign/design_iterations/enhanced_aperonight_theme.css old mode 100644 new mode 100755 diff --git a/.superdesign/design_iterations/neo_brutalist_home.html b/.superdesign/design_iterations/neo_brutalist_home.html old mode 100644 new mode 100755 diff --git a/.superdesign/design_iterations/neo_brutalist_theme.css b/.superdesign/design_iterations/neo_brutalist_theme.css old mode 100644 new mode 100755 diff --git a/.tool-versions b/.tool-versions old mode 100644 new mode 100755 diff --git a/.windsurfrules b/.windsurfrules old mode 100644 new mode 100755 diff --git a/CLAUDE.md b/CLAUDE.md old mode 100644 new mode 100755 diff --git a/CRUSH.md b/CRUSH.md old mode 100644 new mode 100755 diff --git a/Dockerfile b/Dockerfile old mode 100644 new mode 100755 diff --git a/Gemfile b/Gemfile old mode 100644 new mode 100755 diff --git a/Gemfile.lock b/Gemfile.lock old mode 100644 new mode 100755 diff --git a/Procfile.dev b/Procfile.dev old mode 100644 new mode 100755 diff --git a/QWEN.md b/QWEN.md old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 61d6690..8aa646d --- a/README.md +++ b/README.md @@ -1,18 +1,18 @@ -# Aperonight - Party Booking Platform +# Aperonight - Event Booking Platform  ## 🌃 Overview -**Aperonight** is a two-sided marketplace connecting party-goers with nightlife promoters in Paris. The platform allows: +**Aperonight** is a two-sided marketplace connecting event-goers with nightlife promoters in Paris. The platform allows: -- **Customers** to discover/book tickets for upcoming parties +- **Customers** to discover/book tickets for upcoming events - **Promoters** to create/manage events and validate tickets at venue entrances ## 🎯 Key Features -### For Party-Goers -✔ Browse upcoming parties with filters (date, location, music genre) +### For Event-Goers +✔ Browse upcoming events with filters (date, location, music genre) ✔ Book tickets with multiple bundle options (VIP, group passes, etc.) ✔ Secure payment processing (credit cards, Apple/Google Pay) ✔ Mobile-friendly e-tickets with QR codes @@ -52,13 +52,13 @@ erDiagram string email string encrypted_password } - PROMOTER ||--o{ PARTY : creates + PROMOTER ||--o{ EVENT : creates PROMOTER { integer id string stripe_account_id } - PARTY ||--o{ TICKET_TYPE : has - PARTY { + EVENT ||--o{ TICKET_TYPE : has + EVENT { integer id datetime start_time } diff --git a/Rakefile b/Rakefile old mode 100644 new mode 100755 diff --git a/app/assets/builds/.keep b/app/assets/builds/.keep old mode 100644 new mode 100755 diff --git a/app/assets/images/.keep b/app/assets/images/.keep old mode 100644 new mode 100755 diff --git a/app/assets/stylesheets/application.postcss.css b/app/assets/stylesheets/application.postcss.css old mode 100644 new mode 100755 index 421b4fb..eb24773 --- a/app/assets/stylesheets/application.postcss.css +++ b/app/assets/stylesheets/application.postcss.css @@ -10,7 +10,10 @@ @import "components/hero"; @import "components/flash"; @import "components/footer"; -@import "components/party-finder"; +@import "components/event-finder"; + +/* Import pages */ +@import "pages/home"; /* Base styles */ body { diff --git a/app/assets/stylesheets/components/party-finder.css b/app/assets/stylesheets/components/event-finder.css old mode 100644 new mode 100755 similarity index 99% rename from app/assets/stylesheets/components/party-finder.css rename to app/assets/stylesheets/components/event-finder.css index 6f4d9a7..2f2c908 --- a/app/assets/stylesheets/components/party-finder.css +++ b/app/assets/stylesheets/components/event-finder.css @@ -1,4 +1,4 @@ -.party-finder { +.event-finder { background: white; border-radius: var(--radius-2xl); box-shadow: var(--shadow-2xl); @@ -176,7 +176,7 @@ } @media (max-width: 768px) { - .party-finder { + .event-finder { margin: var(--space-8) auto; padding: var(--space-6); } diff --git a/app/assets/stylesheets/components/flash.css b/app/assets/stylesheets/components/flash.css old mode 100644 new mode 100755 diff --git a/app/assets/stylesheets/components/footer.css b/app/assets/stylesheets/components/footer.css old mode 100644 new mode 100755 diff --git a/app/assets/stylesheets/components/hero.css b/app/assets/stylesheets/components/hero.css old mode 100644 new mode 100755 diff --git a/app/assets/stylesheets/pages/home.css b/app/assets/stylesheets/pages/home.css new file mode 100755 index 0000000..c66d87e --- /dev/null +++ b/app/assets/stylesheets/pages/home.css @@ -0,0 +1,171 @@ +/* Updated Featured Events Grid - 3 Cards Side by Side */ + .featured-events-grid { + display: grid; + gap: var(--space-8); + grid-template-columns: 1fr; + } + + @media (min-width: 768px) { + .featured-events-grid { + grid-template-columns: repeat(2, 1fr); + } + } + + @media (min-width: 1024px) { + .featured-events-grid { + grid-template-columns: repeat(3, 1fr); + } + } + + .featured-event-card { + background: white; + border-radius: var(--radius-xl); + overflow: hidden; + box-shadow: var(--shadow-md); + transition: all var(--duration-slow) var(--ease-out); + border: 1px solid var(--color-neutral-200); + position: relative; + } + + .featured-event-card:hover { + transform: translateY(-8px) scale(1.02); + box-shadow: var(--shadow-2xl); + border-color: var(--color-primary-200); + } + + .featured-event-image { + width: 100%; + height: 240px; + object-fit: cover; + transition: transform var(--duration-slow) var(--ease-out); + } + + .featured-event-card:hover .featured-event-image { + transform: scale(1.05); + } + + .featured-event-content { + padding: var(--space-6); + } + + .featured-event-badges { + display: flex; + gap: var(--space-2); + margin-bottom: var(--space-4); + flex-wrap: wrap; + } + + .featured-event-title { + font-family: var(--font-display); + font-size: var(--text-xl); + font-weight: 700; + margin-bottom: var(--space-3); + color: var(--color-neutral-900); + line-height: 1.3; + } + + .featured-event-meta { + display: flex; + flex-direction: column; + gap: var(--space-2); + margin-bottom: var(--space-4); + } + + .featured-event-meta-item { + display: flex; + align-items: center; + gap: var(--space-2); + color: var(--color-neutral-600); + font-size: var(--text-sm); + font-weight: 500; + } + + .featured-event-description { + color: var(--color-neutral-700); + margin-bottom: var(--space-6); + line-height: 1.6; + font-size: var(--text-sm); + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + overflow: hidden; + } + + .featured-event-footer { + display: flex; + justify-content: space-between; + align-items: center; + } + + .featured-event-price { + font-family: var(--font-display); + font-size: var(--text-xl); + font-weight: 800; + color: var(--color-primary-600); + } + + @media (max-width: 768px) { + .featured-event-image { + height: 200px; + } + + .featured-event-content { + padding: var(--space-4); + } + } + + /* Enhanced animations */ + .animate-slideInLeft { + opacity: 0; + transform: translateX(-30px); + transition: all 0.5s var(--ease-out); + } + + .animate-slideInLeft.visible { + opacity: 1; + transform: translateX(0); + } + + .animate-slideInRight { + opacity: 0; + transform: translateX(30px); + transition: all 0.5s var(--ease-out); + } + + .animate-slideInRight.visible { + opacity: 1; + transform: translateX(0); + } + + /* Added missing animation for fadeInUp */ + .animate-fadeInUp { + opacity: 0; + transform: translateY(30px); + transition: all 0.5s var(--ease-out); + } + + .animate-fadeInUp.visible { + opacity: 1; + transform: translateY(0); + } + + /* Feature Stats Styling */ + .feature-stat { + display: flex; + align-items: center; + gap: var(--space-2); + margin-top: var(--space-4); + } + + .stat-number { + font-family: var(--font-display); + font-size: var(--text-2xl); + font-weight: 700; + color: var(--color-primary-600); + } + + .stat-label { + font-size: var(--text-sm); + color: var(--color-neutral-600); + font-weight: 500; + } \ No newline at end of file diff --git a/app/assets/stylesheets/theme.css b/app/assets/stylesheets/theme.css old mode 100644 new mode 100755 diff --git a/app/controllers/api/v1/events_controller.rb b/app/controllers/api/v1/events_controller.rb new file mode 100755 index 0000000..1469a1a --- /dev/null +++ b/app/controllers/api/v1/events_controller.rb @@ -0,0 +1,83 @@ +# Contrôleur API pour la gestion des ressources d'événements +# Fournit des points de terminaison RESTful pour les opérations CRUD sur le modèle Event + +module Api + module V1 + class EventsController < ApiController + # Charge l'évén avant certaines actions pour réduire les duplications + before_action :set_event, only: [ :show, :update, :destroy ] + + # GET /api/v1/events + # Récupère tous les événements triés par date de création (du plus récent au plus ancien) + def index + @events = Event.all.order(created_at: :desc) + render json: @events, status: :ok + end + + # GET /api/v1/events/:id + # Récupère un seul événement par son ID + # Retourne 404 si l'événement n'est pas trouvé + def show + render json: @event, status: :ok + end + + # POST /api/v1/events + # Crée un nouvel événement avec les attributs fournis + # Retourne 201 Created en cas de succès avec les données de l'événement + # Retourne 422 Unprocessable Entity avec les messages d'erreur en cas d'échec + def create + @event = Event.new(event_params) + if @event.save + render json: @event, status: :created + else + render json: { errors: @event.errors.full_messages }, status: :unprocessable_entity + end + end + + # PATCH/PUT /api/v1/events/:id + # Met à jour un événement existant avec les attributs fournis + # Retourne 200 OK avec les données mises à jour en cas de succès + # Retourne 422 Unprocessable Entity avec les messages d'erreur en cas d'échec + def update + if @event.update(event_params) + render json: @event, status: :ok + else + render json: { errors: @event.errors.full_messages }, status: :unprocessable_entity + end + end + + # DELETE /api/v1/events/:id + # Supprime définitivement un événement + # Retourne 204 No Content en cas de succès + def destroy + @event.destroy + head :no_content + end + + private + + # Trouve un événement par son ID ou retourne 404 Introuvable + # Utilisé comme before_action pour les actions show, update et destroy + def set_event + @event = Event.find(params[:id]) + rescue ActiveRecord::RecordNotFound + render json: { error: "Événement non trouvé" }, status: :not_found + end + + # Paramètres forts pour la création et la mise à jour des événements + # Liste blanche des attributs autorisés pour éviter les vulnérabilités de mass assignment + def event_params + params.require(:event).permit( + :name, + :description, + :state, + :venue_name, + :venue_address, + :latitude, + :longitude, + :featured + ) + end + end + end +end diff --git a/app/controllers/api/v1/parties_controller.rb b/app/controllers/api/v1/parties_controller.rb deleted file mode 100644 index c1fd10a..0000000 --- a/app/controllers/api/v1/parties_controller.rb +++ /dev/null @@ -1,82 +0,0 @@ -# API controller for managing party resources -# Provides RESTful endpoints for CRUD operations on Party model -module Api - module V1 - class PartiesController < ApiController - # Load party before specific actions to reduce duplication - before_action :set_party, only: [ :show, :update, :destroy ] - - # GET /api/v1/parties - # Returns all parties sorted by creation date (newest first) - def index - @parties = Party.all.order(created_at: :desc) - render json: @parties, status: :ok - end - - # GET /api/v1/parties/:id - # Returns a single party by ID - # Returns 404 if party is not found - def show - render json: @party, status: :ok - end - - # POST /api/v1/parties - # Creates a new party with provided attributes - # Returns 201 Created on success with party data - # Returns 422 Unprocessable Entity with validation errors on failure - def create - @party = Party.new(party_params) - if @party.save - render json: @party, status: :created - else - render json: { errors: @party.errors.full_messages }, status: :unprocessable_entity - end - end - - # PATCH/PUT /api/v1/parties/:id - # Updates an existing party with provided attributes - # Returns 200 OK with updated party data on success - # Returns 422 Unprocessable Entity with validation errors on failure - def update - if @party.update(party_params) - render json: @party, status: :ok - else - render json: { errors: @party.errors.full_messages }, status: :unprocessable_entity - end - end - - # DELETE /api/v1/parties/:id - # Permanently deletes a party - # Returns 204 No Content on success - def destroy - @party.destroy - head :no_content - end - - private - - # Finds a party by ID or returns 404 Not Found - # Used as before_action for show, update, and destroy actions - def set_party - @party = Party.find(params[:id]) - rescue ActiveRecord::RecordNotFound - render json: { error: "Party not found" }, status: :not_found - end - - # Strong parameters for party creation and updates - # Whitelists permitted attributes to prevent mass assignment vulnerabilities - def party_params - params.require(:party).permit( - :name, - :description, - :state, - :venue_name, - :venue_address, - :latitude, - :longitude, - :featured - ) - end - end - end -end diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb old mode 100644 new mode 100755 diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb old mode 100644 new mode 100755 diff --git a/app/controllers/authentications/confirmations_controller.rb b/app/controllers/authentications/confirmations_controller.rb old mode 100644 new mode 100755 diff --git a/app/controllers/authentications/omniauth_callbacks_controller.rb b/app/controllers/authentications/omniauth_callbacks_controller.rb old mode 100644 new mode 100755 diff --git a/app/controllers/authentications/passwords_controller.rb b/app/controllers/authentications/passwords_controller.rb old mode 100644 new mode 100755 diff --git a/app/controllers/authentications/registrations_controller.rb b/app/controllers/authentications/registrations_controller.rb old mode 100644 new mode 100755 diff --git a/app/controllers/authentications/sessions_controller.rb b/app/controllers/authentications/sessions_controller.rb old mode 100644 new mode 100755 diff --git a/app/controllers/authentications/unlocks_controller.rb b/app/controllers/authentications/unlocks_controller.rb old mode 100644 new mode 100755 diff --git a/app/controllers/concerns/.keep b/app/controllers/concerns/.keep old mode 100644 new mode 100755 diff --git a/app/controllers/parties_controller.rb b/app/controllers/events_controller.rb old mode 100644 new mode 100755 similarity index 68% rename from app/controllers/parties_controller.rb rename to app/controllers/events_controller.rb index e4cbfd1..b3fbdfd --- a/app/controllers/parties_controller.rb +++ b/app/controllers/events_controller.rb @@ -1,22 +1,22 @@ -class PartiesController < ApplicationController +class EventsController < ApplicationController # Display all events def index - @parties = Party.includes(:user).upcoming.page(params[:page]).per(1) - # @parties = Party.page(params[:page]).per(12) + @events = Event.includes(:user).upcoming.page(params[:page]).per(1) + # @events = Event.page(params[:page]).per(12) end # Display desired event def show - @party = Party.find(params[:id]) + @event = Event.find(params[:id]) end # Handle checkout process def checkout - @party = Party.find(params[:id]) + @event = Event.find(params[:id]) cart_data = JSON.parse(params[:cart] || "{}") if cart_data.empty? - redirect_to party_path(@party), alert: "Please select at least one ticket" + redirect_to event_path(@event), alert: "Please select at least one ticket" return end @@ -25,7 +25,7 @@ class PartiesController < ApplicationController total_amount = 0 cart_data.each do |ticket_type_id, item| - ticket_type = @party.ticket_types.find_by(id: ticket_type_id) + ticket_type = @event.ticket_types.find_by(id: ticket_type_id) next unless ticket_type quantity = item["quantity"].to_i @@ -34,7 +34,7 @@ class PartiesController < ApplicationController # Check availability available = ticket_type.quantity - ticket_type.tickets.count if quantity > available - redirect_to party_path(@party), alert: "Not enough tickets available for #{ticket_type.name}" + redirect_to event_path(@event), alert: "Not enough tickets available for #{ticket_type.name}" return end @@ -48,7 +48,7 @@ class PartiesController < ApplicationController end if order_items.empty? - redirect_to party_path(@party), alert: "Invalid order" + redirect_to event_path(@event), alert: "Invalid order" return end @@ -59,6 +59,6 @@ class PartiesController < ApplicationController # For now, we'll just redirect with a success message # In a real app, you'd redirect to a payment page - redirect_to party_path(@party), notice: "Order created successfully! Proceeding to payment..." + redirect_to event_path(@event), notice: "Order created successfully! Proceeding to payment..." end end diff --git a/app/controllers/pages_controller.rb b/app/controllers/pages_controller.rb old mode 100644 new mode 100755 index 50dc752..88b1c89 --- a/app/controllers/pages_controller.rb +++ b/app/controllers/pages_controller.rb @@ -5,10 +5,10 @@ class PagesController < ApplicationController # skip_before_action :authenticate_user!, only: [ :home ] before_action :authenticate_user!, only: [ :dashboard ] - # Homepage showing featured parties + # Homepage showing featured events def home - # @parties = Party.published.featured.limit(3) - # @parties = Party.where(state: :published).order(created_at: :desc) + # @events = Event.published.featured.limit(3) + # @events = Event.where(state: :published).order(created_at: :desc) if user_signed_in? return redirect_to(dashboard_path) @@ -18,15 +18,15 @@ class PagesController < ApplicationController # User dashboard showing personalized content # Accessible only to authenticated users def dashboard - @available_parties = Party.published.count - @events_this_week = Party.published.where("start_time BETWEEN ? AND ?", Date.current.beginning_of_week, Date.current.end_of_week).count - @today_parties = Party.published.where("DATE(start_time) = ?", Date.current).order(start_time: :asc) - @tomorrow_parties = Party.published.where("DATE(start_time) = ?", Date.current + 1).order(start_time: :asc) - @other_parties = Party.published.upcoming.where.not("DATE(start_time) IN (?)", [Date.current, Date.current + 1]).order(start_time: :asc).page(params[:page]) + @available_events = Event.published.count + @events_this_week = Event.published.where("start_time BETWEEN ? AND ?", Date.current.beginning_of_week, Date.current.end_of_week).count + @today_events = Event.published.where("DATE(start_time) = ?", Date.current).order(start_time: :asc) + @tomorrow_events = Event.published.where("DATE(start_time) = ?", Date.current + 1).order(start_time: :asc) + @other_events = Event.published.upcoming.where.not("DATE(start_time) IN (?)", [Date.current, Date.current + 1]).order(start_time: :asc).page(params[:page]) end - # Events page showing all published parties with pagination + # Events page showing all published events with pagination def events - @parties = Party.published.order(created_at: :desc).page(params[:page]) + @events = Event.published.order(created_at: :desc).page(params[:page]) end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb old mode 100644 new mode 100755 diff --git a/app/helpers/flash_messages_helper.rb b/app/helpers/flash_messages_helper.rb old mode 100644 new mode 100755 diff --git a/app/helpers/pages_helper.rb b/app/helpers/pages_helper.rb old mode 100644 new mode 100755 diff --git a/app/javascript/application.js b/app/javascript/application.js old mode 100644 new mode 100755 diff --git a/app/javascript/components/button.jsx b/app/javascript/components/button.jsx old mode 100644 new mode 100755 diff --git a/app/javascript/controllers/application.js b/app/javascript/controllers/application.js old mode 100644 new mode 100755 diff --git a/app/javascript/controllers/counter_controller.js b/app/javascript/controllers/counter_controller.js old mode 100644 new mode 100755 index 129be1d..b463eec --- a/app/javascript/controllers/counter_controller.js +++ b/app/javascript/controllers/counter_controller.js @@ -1,9 +1,9 @@ import { Controller } from "@hotwired/stimulus" export default class extends Controller { - static values = { - target: Number, - decimal: Boolean, + static values = { + target: { type: Number, default: 0 }, + decimal: { type: Boolean, default: false }, duration: { type: Number, default: 2000 } } @@ -27,35 +27,44 @@ export default class extends Controller { } animate() { - const startValue = 0 - const startTime = performance.now() + // Find the target element with data-target-value + const targetElement = this.element.querySelector('.stat-number'); + if (!targetElement) return; + + // Get the target value + this.targetValue = parseInt(targetElement.getAttribute('data-target-value'), 10) || this.targetValue; + + const startValue = 0; + const startTime = performance.now(); const updateCounter = (currentTime) => { - const elapsedTime = currentTime - startTime - const progress = Math.min(elapsedTime / this.durationValue, 1) - + const elapsedTime = currentTime - startTime; + const progress = Math.min(elapsedTime / this.durationValue, 1); + // Easing function for smooth animation - const easeOutQuart = 1 - Math.pow(1 - progress, 4) - - let currentValue = startValue + (this.targetValue - startValue) * easeOutQuart - + const easeOutQuart = 1 - Math.pow(1 - progress, 4); + + let currentValue = startValue + (this.targetValue - startValue) * easeOutQuart; + if (this.decimalValue && this.targetValue < 10) { - currentValue = currentValue.toFixed(1) + currentValue = currentValue.toFixed(1); } else { - currentValue = Math.floor(currentValue) + currentValue = Math.floor(currentValue); } - this.element.textContent = currentValue + // Update only the text content of the target element + targetElement.textContent = currentValue; if (progress < 1) { - requestAnimationFrame(updateCounter) + requestAnimationFrame(updateCounter); } else { - this.element.textContent = this.decimalValue && this.targetValue < 10 - ? this.targetValue.toFixed(1) - : this.targetValue + const finalValue = this.decimalValue && this.targetValue < 10 + ? this.targetValue.toFixed(1) + : this.targetValue; + targetElement.textContent = finalValue; } } - requestAnimationFrame(updateCounter) + requestAnimationFrame(updateCounter); } } diff --git a/app/javascript/controllers/featured_event_controller.js b/app/javascript/controllers/featured_event_controller.js new file mode 100755 index 0000000..8d73a81 --- /dev/null +++ b/app/javascript/controllers/featured_event_controller.js @@ -0,0 +1,86 @@ +import { Controller } from "@hotwired/stimulus" + +export default class extends Controller { + static targets = ["card"] + static classes = ["visible"] + static values = { + threshold: { type: Number, default: 0.1 }, + rootMargin: { type: String, default: '0px 0px -50px 0px' }, + staggerDelay: { type: Number, default: 0.2 } + } + + connect() { + console.log("FeaturedEventController connected") + this.setupIntersectionObserver() + this.setupStaggeredAnimations() + } + + disconnect() { + if (this.observer) { + this.observer.disconnect() + } + } + + setupIntersectionObserver() { + const observerOptions = { + threshold: this.thresholdValue, + rootMargin: this.rootMarginValue + } + + this.observer = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + entry.target.classList.add('visible') + } + }) + }, observerOptions) + + // Observe all card elements within this controller's scope + const elements = this.cardTargets + console.log("Card targets:", elements) + elements.forEach(el => { + this.observer.observe(el) + }) + } + + setupStaggeredAnimations() { + console.log("Setting up staggered animations") + console.log("Card targets:", this.cardTargets) + // Add staggered animation delays to cards + this.cardTargets.forEach((card, index) => { + card.style.transitionDelay = `${index * this.staggerDelayValue}s` + card.classList.remove('visible') + }) + } +} + + +/** Old code + + */ \ No newline at end of file diff --git a/app/javascript/controllers/flash_message_controller.js b/app/javascript/controllers/flash_message_controller.js old mode 100644 new mode 100755 diff --git a/app/javascript/controllers/index.js b/app/javascript/controllers/index.js old mode 100644 new mode 100755 index 8847531..b3c7a46 --- a/app/javascript/controllers/index.js +++ b/app/javascript/controllers/index.js @@ -5,12 +5,15 @@ import { application } from "./application" import LogoutController from "./logout_controller" -import FlashMessage from "./flash_message_controller" +import FlashMessageController from "./flash_message_controller" import CounterController from "./counter_controller" +import FeaturedEventController from "./featured_event_controller" + import ShadcnTestController from "./shadcn_test_controller" application.register("logout", LogoutController) // Allow logout using js -application.register("flash-message", FlashMessage) // Dismiss notification after 5 secondes +application.register("flash-message", FlashMessageController) // Dismiss notification after 5 secondes application.register("counter", CounterController) // Simple counter for homepage +application.register("featured-event", FeaturedEventController) // Featured event controller for homepage application.register("shadcn-test", ShadcnTestController) // Test controller for Shadcn diff --git a/app/javascript/controllers/logout_controller.js b/app/javascript/controllers/logout_controller.js old mode 100644 new mode 100755 diff --git a/app/javascript/controllers/shadcn_test_controller.js b/app/javascript/controllers/shadcn_test_controller.js old mode 100644 new mode 100755 diff --git a/app/javascript/controllers/ticket_cart_controller.js b/app/javascript/controllers/ticket_cart_controller.js old mode 100644 new mode 100755 index 2e8f13d..08d8edf --- a/app/javascript/controllers/ticket_cart_controller.js +++ b/app/javascript/controllers/ticket_cart_controller.js @@ -2,7 +2,7 @@ import { Controller } from "@hotwired/stimulus" export default class extends Controller { static targets = ["quantity", "cartCount", "cartTotal", "checkoutButton"] - static values = { partyId: String } + static values = { eventId: String } connect() { this.cart = {} @@ -78,7 +78,7 @@ export default class extends Controller { const form = document.createElement('form') form.method = 'POST' - form.action = `/parties/${this.partyIdValue}/checkout` + form.action = `/events/${this.eventIdValue}/checkout` form.style.display = 'none' // Add CSRF token diff --git a/app/javascript/lib/utils.js b/app/javascript/lib/utils.js old mode 100644 new mode 100755 diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb old mode 100644 new mode 100755 diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb old mode 100644 new mode 100755 diff --git a/app/models/application_record.rb b/app/models/application_record.rb old mode 100644 new mode 100755 diff --git a/app/models/concerns/.keep b/app/models/concerns/.keep old mode 100644 new mode 100755 diff --git a/app/models/party.rb b/app/models/event.rb old mode 100644 new mode 100755 similarity index 72% rename from app/models/party.rb rename to app/models/event.rb index f772689..6504dd4 --- a/app/models/party.rb +++ b/app/models/event.rb @@ -1,11 +1,11 @@ -# Party model representing nightlife events and parties +# Event model representing nightlife events and events # Manages event details, location data, and publication state -class Party < ApplicationRecord - # Define states for party lifecycle management - # draft: Initial state when party is being created - # published: Party is visible to public and can be discovered - # canceled: Party has been canceled by organizer - # sold_out: Party has reached capacity and tickets are no longer available +class Event < ApplicationRecord + # Define states for Event lifecycle management + # draft: Initial state when Event is being created + # published: Event is visible to public and can be discovered + # canceled: Event has been canceled by organizer + # sold_out: Event has reached capacity and tickets are no longer available enum :state, { draft: 0, published: 1, @@ -18,7 +18,7 @@ class Party < ApplicationRecord has_many :ticket_types, dependent: :destroy has_many :tickets, through: :ticket_types - # Validations for party attributes + # Validations for Event attributes # Basic information validates :name, presence: true, length: { minimum: 3, maximum: 100 } validates :slug, presence: true, length: { minimum: 3, maximum: 100 } @@ -40,12 +40,12 @@ class Party < ApplicationRecord less_than_or_equal_to: 180 } - # Scopes for querying parties with common filters - scope :featured, -> { where(featured: true) } # Get featured parties for homepage - scope :published, -> { where(state: :published) } # Get publicly visible parties + # Scopes for querying events with common filters + scope :featured, -> { where(featured: true) } # Get featured events for homepage + scope :published, -> { where(state: :published) } # Get publicly visible events scope :search_by_name, ->(query) { where("name ILIKE ?", "%#{query}%") } # Search by name (case-insensitive) - # Scope for published parties ordered by start time + # Scope for published events ordered by start time scope :upcoming, -> { published.where("start_time >= ?", Time.current).order(start_time: :asc) } end diff --git a/app/models/ticket.rb b/app/models/ticket.rb old mode 100644 new mode 100755 index 9bb6419..2786194 --- a/app/models/ticket.rb +++ b/app/models/ticket.rb @@ -2,7 +2,7 @@ class Ticket < ApplicationRecord # Associations belongs_to :user belongs_to :ticket_type - has_one :party, through: :ticket_type + has_one :event, through: :ticket_type # Validations validates :qr_code, presence: true, uniqueness: true diff --git a/app/models/ticket_type.rb b/app/models/ticket_type.rb old mode 100644 new mode 100755 index bd3c79c..2d43d75 --- a/app/models/ticket_type.rb +++ b/app/models/ticket_type.rb @@ -1,6 +1,6 @@ class TicketType < ApplicationRecord # Associations - belongs_to :party + belongs_to :event has_many :tickets, dependent: :destroy # Validations @@ -8,12 +8,13 @@ class TicketType < ApplicationRecord validates :description, presence: true, length: { minimum: 10, maximum: 500 } validates :price_cents, presence: true, numericality: { greater_than: 0 } validates :quantity, presence: true, numericality: { only_integer: true, greater_than: 0 } - validates :party_id, presence: true validates :sale_start_at, presence: true validates :sale_end_at, presence: true validate :sale_end_after_start validates :requires_id, inclusion: { in: [ true, false ] } validates :minimum_age, numericality: { only_integer: true, greater_than_or_equal_to: 0, less_than_or_equal_to: 120 }, allow_nil: true + validates :event_id, presence: true + private diff --git a/app/models/user.rb b/app/models/user.rb old mode 100644 new mode 100755 index c2caaee..f7de47c --- a/app/models/user.rb +++ b/app/models/user.rb @@ -20,7 +20,7 @@ class User < ApplicationRecord :recoverable, :rememberable, :validatable # Relationships - has_many :parties, dependent: :destroy + has_many :events, dependent: :destroy has_many :tickets, dependent: :destroy # Validations diff --git a/app/views/components/_party_finder.html.erb b/app/views/components/_event_finder.html.erb old mode 100644 new mode 100755 similarity index 95% rename from app/views/components/_party_finder.html.erb rename to app/views/components/_event_finder.html.erb index 10d0e4a..79639f8 --- a/app/views/components/_party_finder.html.erb +++ b/app/views/components/_event_finder.html.erb @@ -1,10 +1,10 @@ - - + + - + Find Your Perfect Event - Discover afterwork parties tailored to your preferences + Discover afterwork events tailored to your preferences @@ -81,7 +81,7 @@ \ No newline at end of file + + + + + Ready to Join the Community? + Start discovering amazing events and connect with like-minded professionals in your city. + + + + Join Now - Free + + + + Browse Events + + + + + \ No newline at end of file diff --git a/app/views/pages/legals.html.erb b/app/views/pages/legals.html.erb old mode 100644 new mode 100755 diff --git a/app/views/pwa/manifest.json.erb b/app/views/pwa/manifest.json.erb old mode 100644 new mode 100755 diff --git a/app/views/pwa/service-worker.js b/app/views/pwa/service-worker.js old mode 100644 new mode 100755 diff --git a/app/views/shared/_flash_messages.html.erb b/app/views/shared/_flash_messages.html.erb old mode 100644 new mode 100755 diff --git a/auth-messages-implementation-plan.md b/auth-messages-implementation-plan.md old mode 100644 new mode 100755 diff --git a/bun.lock b/bun.lock old mode 100644 new mode 100755 diff --git a/components.json b/components.json old mode 100644 new mode 100755 diff --git a/config.ru b/config.ru old mode 100644 new mode 100755 diff --git a/config/application.rb b/config/application.rb old mode 100644 new mode 100755 diff --git a/config/boot.rb b/config/boot.rb old mode 100644 new mode 100755 diff --git a/config/cable.yml b/config/cable.yml old mode 100644 new mode 100755 diff --git a/config/cache.yml b/config/cache.yml old mode 100644 new mode 100755 diff --git a/config/credentials.yml.enc b/config/credentials.yml.enc old mode 100644 new mode 100755 diff --git a/config/database.yml b/config/database.yml old mode 100644 new mode 100755 diff --git a/config/deploy.yml b/config/deploy.yml old mode 100644 new mode 100755 diff --git a/config/environment.rb b/config/environment.rb old mode 100644 new mode 100755 diff --git a/config/environments/development.rb b/config/environments/development.rb old mode 100644 new mode 100755 diff --git a/config/environments/production.rb b/config/environments/production.rb old mode 100644 new mode 100755 diff --git a/config/environments/test.rb b/config/environments/test.rb old mode 100644 new mode 100755 diff --git a/config/initializers/app_config.rb b/config/initializers/app_config.rb old mode 100644 new mode 100755 diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb old mode 100644 new mode 100755 diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb old mode 100644 new mode 100755 diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb old mode 100644 new mode 100755 diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb old mode 100644 new mode 100755 diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb old mode 100644 new mode 100755 diff --git a/config/locales/devise.en.yml b/config/locales/devise.en.yml old mode 100644 new mode 100755 diff --git a/config/locales/en.yml b/config/locales/en.yml old mode 100644 new mode 100755 diff --git a/config/locales/fr.yml b/config/locales/fr.yml old mode 100644 new mode 100755 diff --git a/config/puma.rb b/config/puma.rb old mode 100644 new mode 100755 diff --git a/config/queue.yml b/config/queue.yml old mode 100644 new mode 100755 diff --git a/config/recurring.yml b/config/recurring.yml old mode 100644 new mode 100755 diff --git a/config/routes.rb b/config/routes.rb old mode 100644 new mode 100755 index fd919e7..f25808a --- a/config/routes.rb +++ b/config/routes.rb @@ -15,10 +15,10 @@ Rails.application.routes.draw do # Pages get "dashboard", to: "pages#dashboard", as: "dashboard" - # Parties - get "parties", to: "parties#index", as: "parties" - get "parties/:slug.:id", to: "parties#show", as: "party" - post "parties/:slug.:id/checkout", to: "parties#checkout", as: "party_checkout" + # events + get "events", to: "events#index", as: "events" + get "events/:slug.:id", to: "events#show", as: "party" + post "events/:slug.:id/checkout", to: "events#checkout", as: "party_checkout" # Routes for devise authentication Gem # Bind devise to user @@ -42,8 +42,8 @@ Rails.application.routes.draw do # API routes versioning namespace :api do namespace :v1 do - # RESTful routes for party management - resources :parties, only: [ :index, :show, :create, :update, :destroy ] + # RESTful routes for event management + resources :events, only: [ :index, :show, :create, :update, :destroy ] # resources :bundles, only: [ :index, :show, :create, :update, :destroy ] diff --git a/config/storage.yml b/config/storage.yml old mode 100644 new mode 100755 diff --git a/db/cable_schema.rb b/db/cable_schema.rb old mode 100644 new mode 100755 diff --git a/db/cache_schema.rb b/db/cache_schema.rb old mode 100644 new mode 100755 diff --git a/db/migrate/20250816145933_devise_create_users.rb b/db/migrate/20250816145933_devise_create_users.rb old mode 100644 new mode 100755 diff --git a/db/migrate/20250823145902_create_parties.rb b/db/migrate/20250823145902_create_events.rb old mode 100644 new mode 100755 similarity index 75% rename from db/migrate/20250823145902_create_parties.rb rename to db/migrate/20250823145902_create_events.rb index 39e100e..e0cca4f --- a/db/migrate/20250823145902_create_parties.rb +++ b/db/migrate/20250823145902_create_events.rb @@ -1,6 +1,6 @@ -class CreateParties < ActiveRecord::Migration[8.0] +class CreateEvents < ActiveRecord::Migration[8.0] def change - create_table :parties do |t| + create_table :events do |t| t.string :name, null: false t.string :slug, null: false t.string :image, null: true @@ -18,8 +18,8 @@ class CreateParties < ActiveRecord::Migration[8.0] t.timestamps end - add_index :parties, :state - add_index :parties, :featured - add_index :parties, [ :latitude, :longitude ] + add_index :events, :state + add_index :events, :featured + add_index :events, [ :latitude, :longitude ] end end diff --git a/db/migrate/20250823170408_create_ticket_types.rb b/db/migrate/20250823170408_create_ticket_types.rb old mode 100644 new mode 100755 index 53ace43..d08f0a7 --- a/db/migrate/20250823170408_create_ticket_types.rb +++ b/db/migrate/20250823170408_create_ticket_types.rb @@ -9,12 +9,12 @@ class CreateTicketTypes < ActiveRecord::Migration[8.0] t.datetime :sale_end_at t.boolean :requires_id t.integer :minimum_age - t.references :party, null: false, foreign_key: false + t.references :event, null: false, foreign_key: false t.timestamps end - add_index :ticket_types, :party_id unless index_exists?(:ticket_types, :party_id) + add_index :ticket_types, :event_id unless index_exists?(:ticket_types, :event_id) add_index :ticket_types, :sale_start_at unless index_exists?(:ticket_types, :sale_start_at) add_index :ticket_types, :sale_end_at unless index_exists?(:ticket_types, :sale_end_at) end diff --git a/db/migrate/20250823171354_create_tickets.rb b/db/migrate/20250823171354_create_tickets.rb old mode 100644 new mode 100755 diff --git a/db/queue_schema.rb b/db/queue_schema.rb old mode 100644 new mode 100755 diff --git a/db/schema.rb b/db/schema.rb old mode 100644 new mode 100755 index 9f42cd7..ffe6170 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # It's strongly recommended that you check this file into your version control system. ActiveRecord::Schema[8.0].define(version: 2025_08_23_171354) do - create_table "parties", charset: "utf8mb4", collation: "utf8mb4_uca1400_ai_ci", force: :cascade do |t| + create_table "events", charset: "utf8mb4", collation: "utf8mb4_uca1400_ai_ci", force: :cascade do |t| t.string "name", null: false t.string "slug", null: false t.string "image" @@ -27,10 +27,10 @@ ActiveRecord::Schema[8.0].define(version: 2025_08_23_171354) do t.bigint "user_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.index ["featured"], name: "index_parties_on_featured" - t.index ["latitude", "longitude"], name: "index_parties_on_latitude_and_longitude" - t.index ["state"], name: "index_parties_on_state" - t.index ["user_id"], name: "index_parties_on_user_id" + t.index ["featured"], name: "index_events_on_featured" + t.index ["latitude", "longitude"], name: "index_events_on_latitude_and_longitude" + t.index ["state"], name: "index_events_on_state" + t.index ["user_id"], name: "index_events_on_user_id" end create_table "ticket_types", charset: "utf8mb4", collation: "utf8mb4_uca1400_ai_ci", force: :cascade do |t| @@ -42,10 +42,10 @@ ActiveRecord::Schema[8.0].define(version: 2025_08_23_171354) do t.datetime "sale_end_at" t.boolean "requires_id" t.integer "minimum_age" - t.bigint "party_id", null: false + t.bigint "event_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.index ["party_id"], name: "index_ticket_types_on_party_id" + t.index ["event_id"], name: "index_ticket_types_on_event_id" t.index ["sale_end_at"], name: "index_ticket_types_on_sale_end_at" t.index ["sale_start_at"], name: "index_ticket_types_on_sale_start_at" end diff --git a/db/seeds.rb b/db/seeds.rb old mode 100644 new mode 100755 diff --git a/docker-compose.yml b/docker-compose.yml old mode 100644 new mode 100755 diff --git a/docs/application-optimization.md b/docs/application-optimization.md old mode 100644 new mode 100755 diff --git a/docs/architecture.md b/docs/architecture.md old mode 100644 new mode 100755 index cac7273..1000d3b --- a/docs/architecture.md +++ b/docs/architecture.md @@ -2,7 +2,7 @@ ## Overview -Aperonight is a Ruby on Rails web application designed for proposing night parties in Paris and allowing party makers to create their own events. The application serves two primary user groups: +Aperonight is a Ruby on Rails web application designed for proposing night parties in Paris and allowing event makers to create their own events. The application serves two primary user groups: ### For Customers: - View upcoming and past parties @@ -30,8 +30,8 @@ create_table :users do |t| t.timestamps end -# Party - Events created by promoters -create_table :parties do |t| +# Event - Events created by promoters +create_table :events do |t| t.string :name t.text :description t.datetime :start_time @@ -46,7 +46,7 @@ create_table :ticket_types do |t| t.string :name t.text :description t.decimal :price - t.integer :party_id + t.integer :event_id t.timestamps end @@ -54,7 +54,7 @@ end create_table :tickets do |t| t.string :uuid t.string :qr_code - t.integer :party_id + t.integer :event_id t.integer :user_id t.integer :ticket_type_id t.boolean :used, default: false @@ -83,19 +83,19 @@ class User < ApplicationRecord has_many :parties, foreign_key: 'promoter_id' end -class Party < ApplicationRecord +class Event < ApplicationRecord belongs_to :promoter, class_name: 'User' has_many :tickets has_many :ticket_types end class TicketType < ApplicationRecord - belongs_to :party + belongs_to :event has_many :tickets end class Ticket < ApplicationRecord - belongs_to :party + belongs_to :event belongs_to :user belongs_to :ticket_type has_one :payment @@ -143,25 +143,25 @@ end ```ruby class PartiesController < ApplicationController before_action :authenticate_user! - before_action :set_party, only: [:show, :edit, :update, :destroy] + before_action :set_event, only: [:show, :edit, :update, :destroy] def index - @parties = Party.all + @parties = Event.all end def show - @ticket_types = @party.ticket_types + @ticket_types = @event.ticket_types end def new - @party = Party.new - @party.ticket_types.build + @event = Event.new + @event.ticket_types.build end def create - @party = current_user.parties.build(party_params) - if @party.save - redirect_to @party, notice: 'Party was successfully created.' + @event = current_user.parties.build(event_params) + if @event.save + redirect_to @event, notice: 'Event was successfully created.' else render :new end @@ -169,12 +169,12 @@ class PartiesController < ApplicationController private - def set_party - @party = Party.find(params[:id]) + def set_event + @event = Event.find(params[:id]) end - def party_params - params.require(:party).permit( + def event_params + params.require(:event).permit( :name, :description, :start_time, :end_time, :location, ticket_types_attributes: [:id, :name, :description, :price, :_destroy] ) @@ -186,7 +186,7 @@ end ```ruby class TicketsController < ApplicationController before_action :authenticate_user! - before_action :set_party, only: [:new, :create] + before_action :set_event, only: [:new, :create] def new @ticket = Ticket.new @@ -217,12 +217,12 @@ class TicketsController < ApplicationController private - def set_party - @party = Party.find(params[:party_id]) + def set_event + @event = Event.find(params[:event_id]) end def ticket_params - params.require(:ticket).permit(:ticket_type_id, :party_id) + params.require(:ticket).permit(:ticket_type_id, :event_id) end end ``` diff --git a/docs/branch-naming.md b/docs/branch-naming.md old mode 100644 new mode 100755 diff --git a/docs/creating-shadcn-react-components.md b/docs/creating-shadcn-react-components.md old mode 100644 new mode 100755 diff --git a/docs/theme-rules.md b/docs/theme-rules.md old mode 100644 new mode 100755 diff --git a/docs/theme-rules.md.old b/docs/theme-rules.md.old old mode 100644 new mode 100755 diff --git a/ecosystem.config.js b/ecosystem.config.js old mode 100644 new mode 100755 diff --git a/env.example b/env.example old mode 100644 new mode 100755 diff --git a/jsconfig.json b/jsconfig.json old mode 100644 new mode 100755 diff --git a/lib/tasks/.keep b/lib/tasks/.keep old mode 100644 new mode 100755 diff --git a/log/.keep b/log/.keep old mode 100644 new mode 100755 diff --git a/npm-install-635.sh b/npm-install-635.sh old mode 100644 new mode 100755 diff --git a/opencode.json b/opencode.json old mode 100644 new mode 100755 diff --git a/package-lock.json b/package-lock.json old mode 100644 new mode 100755 diff --git a/package.json b/package.json old mode 100644 new mode 100755 diff --git a/pm2.sh b/pm2.sh old mode 100644 new mode 100755 diff --git a/postcss.config.js b/postcss.config.js old mode 100644 new mode 100755 diff --git a/public/400.html b/public/400.html old mode 100644 new mode 100755 diff --git a/public/404.html b/public/404.html old mode 100644 new mode 100755 diff --git a/public/406-unsupported-browser.html b/public/406-unsupported-browser.html old mode 100644 new mode 100755 diff --git a/public/422.html b/public/422.html old mode 100644 new mode 100755 diff --git a/public/500.html b/public/500.html old mode 100644 new mode 100755 diff --git a/public/icon.png b/public/icon.png old mode 100644 new mode 100755 diff --git a/public/icon.svg b/public/icon.svg old mode 100644 new mode 100755 diff --git a/public/robots.txt b/public/robots.txt old mode 100644 new mode 100755 diff --git a/rubocop.sh b/rubocop.sh old mode 100644 new mode 100755 diff --git a/script/.keep b/script/.keep old mode 100644 new mode 100755 diff --git a/server.sh b/server.sh old mode 100644 new mode 100755 diff --git a/storage/.keep b/storage/.keep old mode 100644 new mode 100755 diff --git a/tailwind.config.js b/tailwind.config.js old mode 100644 new mode 100755 diff --git a/test.sh b/test.sh old mode 100644 new mode 100755 diff --git a/test.txt b/test.txt new file mode 100755 index 0000000..e69de29 diff --git a/test/application_system_test_case.rb b/test/application_system_test_case.rb old mode 100644 new mode 100755 diff --git a/test/controllers/.keep b/test/controllers/.keep old mode 100644 new mode 100755 diff --git a/test/controllers/pages_controller_test.rb b/test/controllers/pages_controller_test.rb old mode 100644 new mode 100755 diff --git a/test/fixtures/parties.yml b/test/fixtures/events.yml old mode 100644 new mode 100755 similarity index 82% rename from test/fixtures/parties.yml rename to test/fixtures/events.yml index f3f46e6..e2fb610 --- a/test/fixtures/parties.yml +++ b/test/fixtures/events.yml @@ -1,9 +1,9 @@ # Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html one: - name: Summer Party - slug: summer-party - description: A great summer party with music and drinks + name: Summer Event + slug: summer-event + description: A great summer event with music and drinks state: published venue_name: Beach Club venue_address: 123 Ocean Drive diff --git a/test/fixtures/files/.keep b/test/fixtures/files/.keep old mode 100644 new mode 100755 diff --git a/test/fixtures/ticket_types.yml b/test/fixtures/ticket_types.yml old mode 100644 new mode 100755 index 09691d9..6ee6b33 --- a/test/fixtures/ticket_types.yml +++ b/test/fixtures/ticket_types.yml @@ -7,7 +7,7 @@ one: quantity: 100 sale_start_at: <%= 1.day.ago %> sale_end_at: <%= 1.day.from_now %> - party: one + event: one two: name: VIP Access @@ -16,4 +16,4 @@ two: quantity: 50 sale_start_at: <%= 1.day.ago %> sale_end_at: <%= 1.day.from_now %> - party: two \ No newline at end of file + event: two \ No newline at end of file diff --git a/test/fixtures/tickets.yml b/test/fixtures/tickets.yml old mode 100644 new mode 100755 diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml old mode 100644 new mode 100755 diff --git a/test/helpers/.keep b/test/helpers/.keep old mode 100644 new mode 100755 diff --git a/test/integration/.keep b/test/integration/.keep old mode 100644 new mode 100755 diff --git a/test/mailers/.keep b/test/mailers/.keep old mode 100644 new mode 100755 diff --git a/test/models/.keep b/test/models/.keep old mode 100644 new mode 100755 diff --git a/test/models/application_record_test.rb b/test/models/application_record_test.rb old mode 100644 new mode 100755 diff --git a/test/models/event_test.rb b/test/models/event_test.rb new file mode 100755 index 0000000..824c1ae --- /dev/null +++ b/test/models/event_test.rb @@ -0,0 +1,163 @@ +require "test_helper" + +class EventTest < ActiveSupport::TestCase + # Test that Event model exists + test "should be a class" do + assert_kind_of Class, Event + end + + # Test validations + test "should not save event without name" do + event = Event.new(description: "Test event description") + assert_not event.save + end + + test "should not save event without description" do + event = Event.new(name: "Test Event") + assert_not event.save + end + + test "should not save event with name less than 3 characters" do + event = Event.new(name: "AB", description: "Valid description for the event") + assert_not event.save + end + + test "should not save event with description less than 10 characters" do + event = Event.new(name: "Valid Event Name", description: "Too short") + assert_not event.save + end + + test "should not save event without latitude" do + event = Event.new( + name: "Valid Event Name", + description: "Valid description for the event that is long enough", + longitude: 2.3522 + ) + assert_not event.save + end + + test "should not save event without longitude" do + event = Event.new( + name: "Valid Event Name", + description: "Valid description for the event that is long enough", + latitude: 48.8566 + ) + assert_not event.save + end + + test "should not save event with invalid latitude" do + event = Event.new( + name: "Valid Event Name", + description: "Valid description for the event that is long enough", + latitude: 95.0, + longitude: 2.3522, + venue_name: "Test Venue", + venue_address: "123 Test Street" + ) + assert_not event.save + end + + test "should not save event with invalid longitude" do + event = Event.new( + name: "Valid Event Name", + description: "Valid description for the event that is long enough", + latitude: 48.8566, + longitude: 190.0, + venue_name: "Test Venue", + venue_address: "123 Test Street" + ) + assert_not event.save + end + + test "should not save event without slug" do + event = Event.new( + name: "Valid Event Name", + description: "Valid description for the event that is long enough", + latitude: 48.8566, + longitude: 2.3522, + venue_name: "Test Venue", + venue_address: "123 Test Street" + ) + assert_not event.save + end + + test "should not save event with slug less than 3 characters" do + event = Event.new( + name: "Valid Event Name", + description: "Valid description for the event that is long enough", + latitude: 48.8566, + longitude: 2.3522, + venue_name: "Test Venue", + venue_address: "123 Test Street", + slug: "ab" + ) + assert_not event.save + end + + test "should save valid event" do + user = User.create!( + email: "test@example.com", + password: "password123", + password_confirmation: "password123" + ) + + event = Event.new( + name: "Valid Event Name", + slug: "valid-event-name", + description: "Valid description for the event that is long enough", + latitude: 48.8566, + longitude: 2.3522, + venue_name: "Test Venue", + venue_address: "123 Test Street", + user: user, + ) + assert event.save + end + + # Test enum states + test "should have valid states" do + assert_equal %w[draft published canceled sold_out], Event.states.keys + end + + test "should default to draft state" do + event = Event.new( + name: "Valid Event Name", + description: "Valid description for the event that is long enough", + latitude: 48.8566, + longitude: 2.3522, + venue_name: "Test Venue", + venue_address: "123 Test Street" + ) + assert_equal "draft", event.state + end + + # Test associations + test "should belong to user" do + association = Event.reflect_on_association(:user) + assert_equal :belongs_to, association.macro + end + + test "should have many ticket_types" do + association = Event.reflect_on_association(:ticket_types) + assert_equal :has_many, association.macro + end + + test "should have many tickets through ticket_types" do + association = Event.reflect_on_association(:tickets) + assert_equal :has_many, association.macro + assert_equal :ticket_types, association.options[:through] + end + + # Test scopes + test "should respond to featured scope" do + assert_respond_to Event, :featured + end + + test "should respond to published scope" do + assert_respond_to Event, :published + end + + test "should respond to search_by_name scope" do + assert_respond_to Event, :search_by_name + end +end diff --git a/test/models/party_test.rb b/test/models/party_test.rb deleted file mode 100644 index b989051..0000000 --- a/test/models/party_test.rb +++ /dev/null @@ -1,163 +0,0 @@ -require "test_helper" - -class PartyTest < ActiveSupport::TestCase - # Test that Party model exists - test "should be a class" do - assert_kind_of Class, Party - end - - # Test validations - test "should not save party without name" do - party = Party.new(description: "Test party description") - assert_not party.save - end - - test "should not save party without description" do - party = Party.new(name: "Test Party") - assert_not party.save - end - - test "should not save party with name less than 3 characters" do - party = Party.new(name: "AB", description: "Valid description for the party") - assert_not party.save - end - - test "should not save party with description less than 10 characters" do - party = Party.new(name: "Valid Party Name", description: "Too short") - assert_not party.save - end - - test "should not save party without latitude" do - party = Party.new( - name: "Valid Party Name", - description: "Valid description for the party that is long enough", - longitude: 2.3522 - ) - assert_not party.save - end - - test "should not save party without longitude" do - party = Party.new( - name: "Valid Party Name", - description: "Valid description for the party that is long enough", - latitude: 48.8566 - ) - assert_not party.save - end - - test "should not save party with invalid latitude" do - party = Party.new( - name: "Valid Party Name", - description: "Valid description for the party that is long enough", - latitude: 95.0, - longitude: 2.3522, - venue_name: "Test Venue", - venue_address: "123 Test Street" - ) - assert_not party.save - end - - test "should not save party with invalid longitude" do - party = Party.new( - name: "Valid Party Name", - description: "Valid description for the party that is long enough", - latitude: 48.8566, - longitude: 190.0, - venue_name: "Test Venue", - venue_address: "123 Test Street" - ) - assert_not party.save - end - - test "should not save party without slug" do - party = Party.new( - name: "Valid Party Name", - description: "Valid description for the party that is long enough", - latitude: 48.8566, - longitude: 2.3522, - venue_name: "Test Venue", - venue_address: "123 Test Street" - ) - assert_not party.save - end - - test "should not save party with slug less than 3 characters" do - party = Party.new( - name: "Valid Party Name", - description: "Valid description for the party that is long enough", - latitude: 48.8566, - longitude: 2.3522, - venue_name: "Test Venue", - venue_address: "123 Test Street", - slug: "ab" - ) - assert_not party.save - end - - test "should save valid party" do - user = User.create!( - email: "test@example.com", - password: "password123", - password_confirmation: "password123" - ) - - party = Party.new( - name: "Valid Party Name", - slug: "valid-party-name", - description: "Valid description for the party that is long enough", - latitude: 48.8566, - longitude: 2.3522, - venue_name: "Test Venue", - venue_address: "123 Test Street", - user: user, - ) - assert party.save - end - - # Test enum states - test "should have valid states" do - assert_equal %w[draft published canceled sold_out], Party.states.keys - end - - test "should default to draft state" do - party = Party.new( - name: "Valid Party Name", - description: "Valid description for the party that is long enough", - latitude: 48.8566, - longitude: 2.3522, - venue_name: "Test Venue", - venue_address: "123 Test Street" - ) - assert_equal "draft", party.state - end - - # Test associations - test "should belong to user" do - association = Party.reflect_on_association(:user) - assert_equal :belongs_to, association.macro - end - - test "should have many ticket_types" do - association = Party.reflect_on_association(:ticket_types) - assert_equal :has_many, association.macro - end - - test "should have many tickets through ticket_types" do - association = Party.reflect_on_association(:tickets) - assert_equal :has_many, association.macro - assert_equal :ticket_types, association.options[:through] - end - - # Test scopes - test "should respond to featured scope" do - assert_respond_to Party, :featured - end - - test "should respond to published scope" do - assert_respond_to Party, :published - end - - test "should respond to search_by_name scope" do - assert_respond_to Party, :search_by_name - end -end diff --git a/test/models/ticket_test.rb b/test/models/ticket_test.rb old mode 100644 new mode 100755 index d262d39..86f986a --- a/test/models/ticket_test.rb +++ b/test/models/ticket_test.rb @@ -14,10 +14,10 @@ class TicketTest < ActiveSupport::TestCase password_confirmation: "password123" ) - party = Party.create!( - name: "Valid Party Name", - slug: "valid-party-name", - description: "Valid description for the party that is long enough", + event = Event.create!( + name: "Valid event Name", + slug: "valid-event-name", + description: "Valid description for the event that is long enough", latitude: 48.8566, longitude: 2.3522, venue_name: "Test Venue", @@ -33,7 +33,7 @@ class TicketTest < ActiveSupport::TestCase sale_start_at: Time.current, sale_end_at: Time.current + 1.day, requires_id: false, - party: party + event: event ) ticket = Ticket.new(user: user, ticket_type: ticket_type) @@ -87,8 +87,8 @@ class TicketTest < ActiveSupport::TestCase assert_equal :belongs_to, association.macro end - test "should have one party through ticket_type" do - association = Ticket.reflect_on_association(:party) + test "should have one event through ticket_type" do + association = Ticket.reflect_on_association(:event) assert_equal :has_one, association.macro assert_equal :ticket_type, association.options[:through] end @@ -108,10 +108,10 @@ class TicketTest < ActiveSupport::TestCase password_confirmation: "password123" ) - party = Party.create!( - name: "Valid Party Name", - slug: "valid-party-name", - description: "Valid description for the party that is long enough", + event = Event.create!( + name: "Valid event Name", + slug: "valid-event-name", + description: "Valid description for the event that is long enough", latitude: 48.8566, longitude: 2.3522, venue_name: "Test Venue", @@ -127,7 +127,7 @@ class TicketTest < ActiveSupport::TestCase sale_start_at: Time.current, sale_end_at: Time.current + 1.day, requires_id: false, - party: party + event: event ) ticket = Ticket.new( @@ -147,10 +147,10 @@ class TicketTest < ActiveSupport::TestCase password_confirmation: "password123" ) - party = Party.create!( - name: "Valid Party Name", - slug: "valid-party-name", - description: "Valid description for the party that is long enough", + event = Event.create!( + name: "Valid event Name", + slug: "valid-event-name", + description: "Valid description for the event that is long enough", latitude: 48.8566, longitude: 2.3522, venue_name: "Test Venue", @@ -166,7 +166,7 @@ class TicketTest < ActiveSupport::TestCase sale_start_at: Time.current, sale_end_at: Time.current + 1.day, requires_id: false, - party: party + event: event ) ticket = Ticket.new( @@ -185,10 +185,10 @@ class TicketTest < ActiveSupport::TestCase password_confirmation: "password123" ) - party = Party.create!( - name: "Valid Party Name", - slug: "valid-party-name", - description: "Valid description for the party that is long enough", + event = Event.create!( + name: "Valid event Name", + slug: "valid-event-name", + description: "Valid description for the event that is long enough", latitude: 48.8566, longitude: 2.3522, venue_name: "Test Venue", @@ -204,7 +204,7 @@ class TicketTest < ActiveSupport::TestCase sale_start_at: Time.current, sale_end_at: Time.current + 1.day, requires_id: false, - party: party + event: event ) ticket = Ticket.new( @@ -223,10 +223,10 @@ class TicketTest < ActiveSupport::TestCase password_confirmation: "password123" ) - party = Party.create!( - name: "Valid Party Name", - slug: "valid-party-name", - description: "Valid description for the party that is long enough", + event = Event.create!( + name: "Valid event Name", + slug: "valid-event-name", + description: "Valid description for the event that is long enough", latitude: 48.8566, longitude: 2.3522, venue_name: "Test Venue", @@ -242,7 +242,7 @@ class TicketTest < ActiveSupport::TestCase sale_start_at: Time.current, sale_end_at: Time.current + 1.day, requires_id: false, - party: party + event: event ) ticket = Ticket.new( diff --git a/test/models/ticket_type_test.rb b/test/models/ticket_type_test.rb old mode 100644 new mode 100755 index c09cd09..3aea6b0 --- a/test/models/ticket_type_test.rb +++ b/test/models/ticket_type_test.rb @@ -88,10 +88,10 @@ class TicketTypeTest < ActiveSupport::TestCase password_confirmation: "password123" ) - party = Party.create!( - name: "Valid Party Name", - slug: "valid-party-name", - description: "Valid description for the party that is long enough", + event = Event.create!( + name: "Valid event Name", + slug: "valid-event-name", + description: "Valid description for the event that is long enough", latitude: 48.8566, longitude: 2.3522, venue_name: "Test Venue", @@ -107,14 +107,14 @@ class TicketTypeTest < ActiveSupport::TestCase sale_start_at: Time.current, sale_end_at: Time.current + 1.day, requires_id: false, - party: party + event: event ) assert ticket_type.save end # Test associations - test "should belong to party" do - association = TicketType.reflect_on_association(:party) + test "should belong to event" do + association = TicketType.reflect_on_association(:event) assert_equal :belongs_to, association.macro end @@ -131,10 +131,10 @@ class TicketTypeTest < ActiveSupport::TestCase password_confirmation: "password123" ) - party = Party.create!( - name: "Valid Party Name", - slug: "valid-party-name", - description: "Valid description for the party that is long enough", + event = Event.create!( + name: "Valid event Name", + slug: "valid-event-name", + description: "Valid description for the event that is long enough", latitude: 48.8566, longitude: 2.3522, venue_name: "Test Venue", @@ -150,7 +150,7 @@ class TicketTypeTest < ActiveSupport::TestCase sale_start_at: Time.current, sale_end_at: Time.current + 1.day, requires_id: true, - party: party + event: event ) assert ticket_type.save end @@ -162,10 +162,10 @@ class TicketTypeTest < ActiveSupport::TestCase password_confirmation: "password123" ) - party = Party.create!( - name: "Valid Party Name", - slug: "valid-party-name", - description: "Valid description for the party that is long enough", + event = Event.create!( + name: "Valid event Name", + slug: "valid-event-name", + description: "Valid description for the event that is long enough", latitude: 48.8566, longitude: 2.3522, venue_name: "Test Venue", @@ -181,7 +181,7 @@ class TicketTypeTest < ActiveSupport::TestCase sale_start_at: Time.current, sale_end_at: Time.current + 1.day, requires_id: false, - party: party + event: event ) assert ticket_type.save end @@ -194,10 +194,10 @@ class TicketTypeTest < ActiveSupport::TestCase password_confirmation: "password123" ) - party = Party.create!( - name: "Valid Party Name", - slug: "valid-party-name", - description: "Valid description for the party that is long enough", + event = Event.create!( + name: "Valid event Name", + slug: "valid-event-name", + description: "Valid description for the event that is long enough", latitude: 48.8566, longitude: 2.3522, venue_name: "Test Venue", @@ -214,7 +214,7 @@ class TicketTypeTest < ActiveSupport::TestCase sale_end_at: Time.current + 1.day, requires_id: false, minimum_age: nil, - party: party + event: event ) assert ticket_type.save end diff --git a/test/models/user_test.rb b/test/models/user_test.rb old mode 100644 new mode 100755 index 48b362e..b2f7ce5 --- a/test/models/user_test.rb +++ b/test/models/user_test.rb @@ -14,8 +14,8 @@ class UserTest < ActiveSupport::TestCase end # Test associations - test "should have many parties" do - association = User.reflect_on_association(:parties) + test "should have many events" do + association = User.reflect_on_association(:events) assert_equal :has_many, association.macro assert_equal :destroy, association.options[:dependent] end diff --git a/test/system/.keep b/test/system/.keep old mode 100644 new mode 100755 diff --git a/test/test_helper.rb b/test/test_helper.rb old mode 100644 new mode 100755 diff --git a/tmp/.keep b/tmp/.keep old mode 100644 new mode 100755 diff --git a/tmp/pids/.keep b/tmp/pids/.keep old mode 100644 new mode 100755 diff --git a/tmp/storage/.keep b/tmp/storage/.keep old mode 100644 new mode 100755 diff --git a/vendor/.keep b/vendor/.keep old mode 100644 new mode 100755 diff --git a/yarn.lock b/yarn.lock old mode 100644 new mode 100755
Discover afterwork parties tailored to your preferences
Discover afterwork events tailored to your preferences
Start discovering amazing events and connect with like-minded professionals in your city.