diff --git a/Gemfile b/Gemfile
index 0e1dbade..6edef993 100644
--- a/Gemfile
+++ b/Gemfile
@@ -103,6 +103,8 @@ group :development do
gem 'asciidoctor'
gem 'capistrano'
# gem 'rack-mini-profiler'
+ gem 'better_errors'
+ gem 'binding_of_caller'
gem 'web-console'
end
diff --git a/Gemfile.lock b/Gemfile.lock
index 67a2b7f9..ce28fb36 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -91,8 +91,14 @@ GEM
awesome_print (1.9.2)
base64 (0.2.0)
bcrypt (3.1.20)
+ better_errors (2.10.1)
+ erubi (>= 1.0.0)
+ rack (>= 0.9.0)
+ rouge (>= 1.0.0)
bigdecimal (3.1.7)
bindex (0.8.1)
+ binding_of_caller (1.0.1)
+ debug_inspector (>= 1.2.0)
bootsnap (1.18.3)
msgpack (~> 1.2)
brakeman (6.1.2)
@@ -129,6 +135,7 @@ GEM
debug (1.9.2)
irb (~> 1.10)
reline (>= 0.3.8)
+ debug_inspector (1.2.0)
devise (4.9.4)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
@@ -314,6 +321,7 @@ GEM
actionpack (>= 5.2)
railties (>= 5.2)
rexml (3.2.6)
+ rouge (4.2.1)
rspec (3.13.0)
rspec-core (~> 3.13.0)
rspec-expectations (~> 3.13.0)
@@ -450,6 +458,8 @@ DEPENDENCIES
attribute_normalizer
awesome_print
bcrypt (~> 3.1.7)
+ better_errors
+ binding_of_caller
bootsnap
brakeman
capistrano
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 39b292e0..73b86468 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+require 'colorize'
+
# General controller configuration and helpers.
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
@@ -11,20 +13,24 @@ class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
# By default, enable friendly forwarding if user is logged in
- before_action :set_redirect_path, unless: :user_signed_in?
+ before_action :redirect_path, unless: :user_signed_in?
add_flash_types :info, :error, :warning
protected
- def set_redirect_path
- @redirect_path = request.path
+ def stripe_publishable_api_key
+ @stripe_publishable_api_key ||= ::Rails.application.credentials[Rails.env.to_sym].stripe.publishable_api_key
+ end
+
+ def stripe_secret_api_key
+ @stripe_secret_api_key ||= ::Rails.application.credentials[Rails.env.to_sym].stripe.secret_api_key
end
# Override a Devise method
def after_sign_in_path_for(resource)
- if params[:redirect_to].present?
- store_location_for(resource, params[:redirect_to])
+ if redirect_to_param.present?
+ store_location_for(resource, redirect_to_param)
elsif request.referer == Routing.routes.new_user_session_url
super
else
@@ -32,6 +38,14 @@ def after_sign_in_path_for(resource)
end
end
+ def redirect_path
+ @redirect_path = redirect_to_param || request.path
+ end
+
+ def redirect_to_param
+ @redirect_to_param ||= params.permit(:redirect_to)[:redirect_to]
+ end
+
def require_site_admin
redirect_to root_path unless current_user.site_admin?
end
@@ -71,9 +85,19 @@ def alert_log_level(alert_type)
end
end
+ def alert_log_color(alert_type)
+ case alert_type
+ when 'notice' then :blue
+ when 'error', 'alert' then :red
+ when 'warning' then :yellow
+ end
+ end
+
def render_flash(flash)
flash.each do |type, msg|
log_level = alert_log_level(type) || :error
+ color = alert_log_color(type)
+ msg = msg.colorize(color).colorize(:bold) if color
Rails.logger.send(log_level, msg)
end
diff --git a/app/controllers/payments_controller.rb b/app/controllers/payments_controller.rb
index 91487aac..cd8a2ead 100644
--- a/app/controllers/payments_controller.rb
+++ b/app/controllers/payments_controller.rb
@@ -4,7 +4,7 @@ class PaymentsController < ApplicationController
before_action :authenticate_user!
def show
- @payment = Payment.find(params[:id])
+ @payment = Payment.find(permit_params[:id])
@charge = Stripe::Charge.retrieve(@payment.stripe_charge_id) if @payment.stripe_charge_id
@ticket_request = @payment.ticket_request
@event = @ticket_request.event
@@ -12,9 +12,8 @@ def show
end
def new
- @ticket_request = TicketRequest.find(params[:ticket_request_id])
+ @ticket_request = TicketRequest.find(permit_params[:ticket_request_id])
return redirect_to root_path unless @ticket_request.can_view?(current_user)
- return redirect_to payment_path(@ticket_request.payment) if @ticket_request.payment
@event = @ticket_request.event
@@ -33,7 +32,7 @@ def new
end
def create
- @payment = Payment.new(params[:payment])
+ @payment = Payment.new(permit_params[:payment])
return redirect_to root_path unless @payment.can_view?(current_user)
if @payment.save_and_charge!
@@ -49,7 +48,7 @@ def create
end
def other
- @ticket_request = TicketRequest.find(params[:ticket_request_id])
+ @ticket_request = TicketRequest.find(permit_params[:ticket_request_id])
return redirect_to root_path unless @ticket_request.can_view?(current_user)
return redirect_to payment_path(@ticket_request.payment) if @ticket_request.payment
@@ -57,11 +56,11 @@ def other
end
def sent
- @ticket_request = TicketRequest.find(params[:ticket_request_id])
+ @ticket_request = TicketRequest.find(permit_params[:ticket_request_id])
return redirect_to root_path unless @ticket_request.can_view?(current_user)
@payment = Payment.new(ticket_request_id: @ticket_request.id,
- explanation: params[:explanation],
+ explanation: permit_params[:explanation],
status: Payment::STATUS_IN_PROGRESS)
if @payment.save
flash[:notice] = "We've recorded that your payment is en route"
@@ -73,7 +72,7 @@ def sent
end
def mark_received
- @ticket_request = TicketRequest.find(params[:ticket_request_id])
+ @ticket_request = TicketRequest.find(permit_params[:ticket_request_id])
return redirect_to root_path unless @ticket_request.can_view?(current_user)
@payment = Payment.where(ticket_request_id: @ticket_request.id,
@@ -87,4 +86,22 @@ def mark_received
redirect_to :back
end
end
+
+ private
+
+ def permit_params
+ params.permit(
+ :id,
+ :ticket_request_id,
+ payment: %i[
+ ticket_request_id
+ ticket_request_attributes
+ status
+ stripe_card_token
+ explanation
+ ]
+ )
+ .to_hash
+ .with_indifferent_access
+ end
end
diff --git a/app/controllers/ticket_requests_controller.rb b/app/controllers/ticket_requests_controller.rb
index 04250a2f..106391f4 100644
--- a/app/controllers/ticket_requests_controller.rb
+++ b/app/controllers/ticket_requests_controller.rb
@@ -153,8 +153,10 @@ def create
redirect_to new_payment_url(ticket_request_id: @ticket_request)
end
rescue StandardError => e
- Rails.logger.error("Error saving request: #{e.message}\n\n#{@ticket_request.errors.full_messages.join(', ')}")
- flash.now[:error] = "Error saving request: #{e.message}
#{@ticket_request.errors.full_messages.join("\n- ")}"
+ Rails.logger.error("Error Processing Ticket Send Request: #{e.message}\n\n#{@ticket_request.errors.full_messages.join(', ')}")
+ @ticket_request.destroy if @ticket_request.persisted?
+ flash.now[:error] =
+ "Error Processing Ticket Request — #{e.message}. Please contact the Event Admins and let them know — #{@event.admin_contacts.join(', ')}."
render_flash(flash)
end
end
@@ -162,9 +164,18 @@ def create
def update
# Allow ticket request to edit guests and nothing else
- permitted_params[:ticket_request].slice!(:guests) unless @event.admin?(current_user)
+ ticket_request_params = permitted_params[:ticket_request]
- if @ticket_request.update(permitted_params[:ticket_request])
+ guests = (Array(ticket_request_params[:guest_list]) || []).flatten
+ ticket_request_params.delete(:guest_list)
+
+ Rails.logger.info("guests: #{guests.inspect}")
+ Rails.logger.info("params: #{permitted_params.inspect}")
+
+ ticket_request_params[:guests] = guests
+ Rails.logger.info("ticket_request_params: #{ticket_request_params.inspect}")
+
+ if @ticket_request.update(ticket_request_params)
redirect_to event_ticket_request_path(@event, @ticket_request)
else
render action: 'edit'
@@ -177,12 +188,12 @@ def approve
user: current_user,
target: @ticket_request
).fire!
- flash[:notice] = "#{@ticket_request.user.name}'s request was approved"
+ flash.now[:notice] = "#{@ticket_request.user.name}'s request was approved"
else
- flash[:error] = "Unable to approve #{@ticket_request.user.name}'s request"
+ flash.now[:error] = "Unable to approve #{@ticket_request.user.name}'s request"
end
- redirect_to event_ticket_requests_path(@event)
+ render_flash(flash) && redirect_to(event_ticket_requests_path(@event))
end
def decline
@@ -196,13 +207,18 @@ def decline
flash[:error] = "Unable to decline #{@ticket_request.user.name}'s request"
end
- redirect_to event_ticket_requests_path(@event)
+ render_flash(flash) && redirect_to(event_ticket_requests_path(@event))
end
def resend_approval
- TicketRequestMailer.request_approved(@ticket_request).deliver_now if @ticket_request.awaiting_payment?
+ unless @ticket_request.awaiting_payment?
+ flash.now[:error] = 'Ticket request does not qualify for a payment yet.'
+ return render_flash(flash)
+ end
- redirect_to event_ticket_requests_path(@event)
+ TicketRequestMailer.request_approved(@ticket_request).deliver_now
+ flash.now[:notice] = 'Approval requests has been resent.'
+ render_flash(flash)
end
def revert_to_pending
@@ -224,7 +240,13 @@ def refund
private
def set_event
- @event = Event.where(id: permitted_params[:event_id].to_i).first
+ event_id = permitted_params[:event_id].to_i
+ Rails.logger.debug { "#set_event() => event_id = #{event_id}, params[:event_id] => #{permitted_params[:event_id]}" }
+ @event = Event.where(id: event_id).first
+ if @event.nil?
+ flash.now[:error] = "Event with id #{event_id} was not found."
+ raise ArgumentError, flash.now[:error]
+ end
end
def set_ticket_request
@@ -241,33 +263,33 @@ def permitted_params
:password,
:authenticity_token,
:commit,
- ticket_request: %i[
- user_id
- adults
- kids
- cabins
- needs_assistance
- notes
- special_price
- event_id
- user
- donation
- role
- role_explanation
- car_camping
- car_camping_explanation
- previous_contribution
- address_line1
- address_line2
- city
- state
- zip_code
- country_code
- admin_notes
- agrees_to_terms
- early_arrival_passes
- late_departure_passes
- guests
+ ticket_request: [
+ :user_id,
+ :adults,
+ :kids,
+ :cabins,
+ :needs_assistance,
+ :notes,
+ :special_price,
+ :event_id,
+ :user,
+ :donation,
+ :role,
+ :role_explanation,
+ :car_camping,
+ :car_camping_explanation,
+ :previous_contribution,
+ :address_line1,
+ :address_line2,
+ :city,
+ :state,
+ :zip_code,
+ :country_code,
+ :admin_notes,
+ :agrees_to_terms,
+ :early_arrival_passes,
+ :late_departure_passes,
+ { guest_list: [] }
]
)
.to_hash
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 0c09fc0b..74aa8b1b 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -16,10 +16,6 @@ def help_mark(help_text, options = {})
end
end
- def stripe_publishable_api_key
- TicketBooth::Application.config.x.stripe.public_key
- end
-
def alert_class(alert_type)
case alert_type
when 'notice' then 'alert-info'
diff --git a/app/javascript/add_jquery.js b/app/javascript/add_jquery.js
index f75831dc..a464e146 100644
--- a/app/javascript/add_jquery.js
+++ b/app/javascript/add_jquery.js
@@ -8,7 +8,15 @@ addEventListener("turbo:before-frame-render", (event) => {
if (document.startViewTransition) {
const originalRender = event.detail.render
event.detail.render = (currentElement, newElement) => {
- document.startViewTransition(()=> originalRender(currentElement, newElement))
+ document.startViewTransition(() => originalRender(currentElement, newElement))
}
}
})
+
+
+// open a popup
+window.popupWindow = function(url, windowName, win, w, h) {
+ const y = win.top.outerHeight / 2 + win.top.screenY - (h / 2);
+ const x = win.top.outerWidth / 2 + win.top.screenX - (w / 2);
+ return win.open(url, windowName, `toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=${w}, height=${h}, top=${y}, left=${x}`);
+};
diff --git a/app/mailers/ticket_request_mailer.rb b/app/mailers/ticket_request_mailer.rb
index 5fe12e44..7f12ec29 100644
--- a/app/mailers/ticket_request_mailer.rb
+++ b/app/mailers/ticket_request_mailer.rb
@@ -39,8 +39,8 @@ def request_approved(ticket_request)
# Generate an authentication token for the user
@auth_token = ticket_request&.user&.generate_auth_token!
- @payment_url = new_payment_url(ticket_request: @ticket_request,
- user: @ticket_request.user,
+ @payment_url = new_payment_url(ticket_request_id: @ticket_request.id,
+ user_id: @ticket_request.user.id,
user_token: @auth_token)
if @event.eald?
@@ -77,9 +77,7 @@ def to_email
class << self
def mail_config
- TicketBooth::Application.configure do |config|
- return config.action_mailer
- end
+ TicketBooth::Application.config.action_mailer
end
def ticket_request(event)
diff --git a/app/models/event.rb b/app/models/event.rb
index 6fe02270..366a96bb 100644
--- a/app/models/event.rb
+++ b/app/models/event.rb
@@ -39,6 +39,8 @@ class Event < ApplicationRecord
MAX_NAME_LENGTH = 100
+ GUEST_LIST_FINAL_WITHIN = 2.days
+
attr_accessible :name, :start_time, :end_time, :adult_ticket_price,
:early_arrival_price, :late_departure_price,
:kid_ticket_price, :cabin_price, :max_adult_tickets_per_request,
@@ -114,6 +116,10 @@ def admin?(user)
user && (user.site_admin? || admins.exists?(id: user))
end
+ def admin_contacts
+ admins.map(&:name_and_email)
+ end
+
def make_admin(user)
return false if admin?(user)
diff --git a/app/models/ticket_request.rb b/app/models/ticket_request.rb
index 7460cbb9..8d12393c 100644
--- a/app/models/ticket_request.rb
+++ b/app/models/ticket_request.rb
@@ -49,6 +49,14 @@ class TicketRequest < ApplicationRecord
STATUS_REFUNDED = 'R'
].freeze
+ STATUS_NAMES = {
+ 'P' => 'Pending',
+ 'A' => 'Waiting for Payment',
+ 'D' => 'Declined',
+ 'C' => 'Completed',
+ 'R' => 'Refunded'
+ }.freeze
+
TICKET_LIMITS = {
(ROLE_UBER_COORDINATOR = 'uber_coordinator') => 12,
(ROLE_COORDINATOR = 'coordinator') => 10,
@@ -139,6 +147,10 @@ def can_view?(user)
self.user == user || event.admin?(user)
end
+ def status_name
+ STATUS_NAMES[status]
+ end
+
def completed?
status == STATUS_COMPLETED
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 5b2697f9..647b32db 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -96,6 +96,10 @@ def site_admin?
site_admin.present?
end
+ def name_and_email
+ "#{name} <#{email}>"
+ end
+
def event_admin?
event_admins.present? && !event_admins.empty?
end
diff --git a/app/views/devise/sessions/new.html.haml b/app/views/devise/sessions/new.html.haml
index 5e8ac856..a4a358cd 100644
--- a/app/views/devise/sessions/new.html.haml
+++ b/app/views/devise/sessions/new.html.haml
@@ -1,5 +1,5 @@
-= render partial: "devise/shared/login", locals: { resource: resource, resource_name: resource_name }
+= render partial: "devise/shared/login", locals: { resource: resource, resource_name: resource_name, redirect_to: controller.send(:redirect_to_param) }
%hr
diff --git a/app/views/devise/shared/_login.html.haml b/app/views/devise/shared/_login.html.haml
index 8e0ef56a..8646362f 100644
--- a/app/views/devise/shared/_login.html.haml
+++ b/app/views/devise/shared/_login.html.haml
@@ -1,6 +1,6 @@
%h2 Log in
-= form_for(resource, as: resource_name, url: session_path(resource_name, location: request.path), data: { "turbo": false } ) do |f|
+= form_for(resource, as: resource_name, url: session_path(resource_name), data: { "turbo": false } ) do |f|
= hidden_field_tag :authenticity_token, form_authenticity_token
.row
.col-md-6.col-sm-12
diff --git a/app/views/eald_payments/new.html.haml b/app/views/eald_payments/new.html.haml
index ea7c8a2b..04d7f787 100644
--- a/app/views/eald_payments/new.html.haml
+++ b/app/views/eald_payments/new.html.haml
@@ -1,8 +1,8 @@
- content_for(:meta) do
- %meta{ name: 'stripe-key', content: STRIPE_PUBLIC_KEY }
+ %meta{ name: 'stripe-key', content: Rails.application.credentials.send(Rails.env.to_sym).stripe.publishable_api_key}
- content_for(:head) do
- = javascript_include_tag 'https://js.stripe.com/v1/'
+ = javascript_include_tag 'https://js.stripe.com/v3/'
%h1
Early Arrival / Late Departure Passes
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index d1c25344..74e40d7c 100644
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -4,7 +4,7 @@
%meta{:content => "text/html; charset=UTF-8", "http-equiv" => "Content-Type"}/
%meta{:content => "width=device-width,initial-scale=1", :name => "viewport"}/
%meta{:content => "yes", :name => "apple-mobile-web-app-capable"}/
- %meta{:content => "#{stripe_publishable_api_key}", :name => "stripe-key"}/
+ %meta{:content => "#{controller.send(:stripe_publishable_api_key)}", :name => "stripe-key"}/
%link{:href => "/icons/nav-bar-logo.png", :rel => "shortcut icon", :type => "image/png"}/
%link{:href => "https://fonts.googleapis.com", :rel => "preconnect"}/
%link{:crossorigin => "", :href => "https://fonts.gstatic.com", :rel => "preconnect"}/
diff --git a/app/views/payments/_form.html.haml b/app/views/payments/_form.html.haml
index 7b07387f..b88f00bc 100644
--- a/app/views/payments/_form.html.haml
+++ b/app/views/payments/_form.html.haml
@@ -1,70 +1,76 @@
-= form_for(@payment) do |f|
- = render 'shared/form_errors', resource: @payment
+.card
+ .card-header.bg-secondary-subtle
+ %h4 Please Enter Your Credit Card Details
- = f.hidden_field :ticket_request_id, value: @ticket_request.id
- = f.hidden_field :stripe_card_token, id: 'stripe_card_token' # Value set by JS
+ .card-body
+ = form_for(@payment) do |f|
+ = render 'shared/form_errors', resource: @payment
- .field
- = label_tag :card_number, 'Credit Card Number'
- = text_field_tag :card_number, nil, name: nil, maxlength: 16, class: 'input-large'
- %span.help-inline
- - %w[visa mastercard american_express discover jcb].each do |company|
- = image_tag "credit-cards/#{company}_32.png"
+ = f.hidden_field :ticket_request_id, value: @ticket_request.id
+ = f.hidden_field :stripe_card_token, id: 'stripe_card_token' # Value set by JS
+
+ .field
+ = label_tag :card_number, 'Credit Card Number'
+ = text_field_tag :card_number, nil, name: nil, maxlength: 16, class: 'input-large'
+ %span.help-inline
+ - %w[visa mastercard american_express discover jcb].each do |company|
+ = image_tag "credit-cards/#{company}_32.png"
- .field
- = label_tag :card_code, 'Card Verification Code'
- = text_field_tag :card_code, nil, name: nil, class: 'input-mini', maxlength: 6,
- placeholder: 'XXX'
- .field
- = label_tag :card_month, 'Expiration Date'
- = select_month nil, { add_month_numbers: true },
- { name: nil, id: 'card_month', class: 'input-medium' }
- = select_year nil, { start_year: Date.today.year, end_year: Date.today.year + 15 },
- { name: nil, id: 'card_year', class: 'input-small' }
+ .field
+ = label_tag :card_month, 'Expiration Date'
+ = select_month nil, { add_month_numbers: true },
+ { name: nil, id: 'card_month', class: 'input-medium' }
+ = select_year nil, { start_year: Date.today.year, end_year: Date.today.year + 15 },
+ { name: nil, id: 'card_year', class: 'input-small' }
- - if @event.allow_donations
- = f.fields_for :ticket_request, @ticket_request do |ff|
.field
- = label_tag :donation do
- Community Fund Donation
- = help_mark help_text_for(:community_fund_donation)
- - [0, 10, 25, 50, 100].each do |amount|
- .donation-option
- = ff.radio_button :donation, amount, checked: amount == 0
- = ff.label :donation, "$#{amount}", value: amount, class: 'radio inline'
+ = label_tag :card_code, 'CVV'
+ = text_field_tag :card_code, nil, name: nil, class: 'input-mini', maxlength: 6,
+ placeholder: '', style: 'width: 60px'
+
+ - if @event.allow_donations
+ = f.fields_for :ticket_request, @ticket_request do |ff|
+ .field
+ = label_tag :donation do
+ Community Fund Donation
+ = help_mark help_text_for(:community_fund_donation)
+ - [0, 10, 25, 50, 100].each do |amount|
+ .donation-option
+ = ff.radio_button :donation, amount, checked: amount == 0
+ = ff.label :donation, "$#{amount}", value: amount, class: 'radio inline'
- %hr
+ %hr
- %p
- Clicking "Pay Now" will charge
- %strong.text-success#total_price{ data: { price: @ticket_request.price } }
- = number_to_currency(@payment.ticket_request.price)
- - extra = extra_amount_to_charge(@payment.ticket_request.price)
- - if extra > 0
- +
- %strong.text-success#total_fee
- = number_to_currency(extra)
- processing fee
- to the card entered above.
- = help_mark 'This fee covers the the fees charged by our credit card processor, Stripe.'
+ %p
+ Clicking "Pay Now" will charge
+ %strong.text-success#total_price{ data: { price: @ticket_request.price } }
+ = number_to_currency(@payment.ticket_request.price)
+ - extra = extra_amount_to_charge(@payment.ticket_request.price)
+ - if extra > 0
+ +
+ %strong.text-success#total_fee
+ = number_to_currency(extra)
+ processing fee
+ to the card entered above.
+ = help_mark 'This fee covers the the fees charged by our credit card processor, Stripe.'
- %p
- By purchasing tickets to an FnF event, you acknowledge that you have read
- = link_to 'The FnF Way', 'http://cfaea.net/the-fnf-way/'
- and
- = link_to 'Code of Conduct', 'https://fnf.page.link/coc'
- and are responsible for sharing these documents with your guests. You
- further understand that you are responsible for the conduct of your guests
- while they attend an FnF event. By making clear the values that inform our
- events and setting the expectation of conduct at our events, we hope to
- continue to embrace radical self-expression while continuing to invite new
- and diverse people into our community.
+ %p.small
+ By purchasing tickets to an FnF event, you acknowledge that you have read
+ = link_to 'The FnF Way', 'http://cfaea.net/the-fnf-way/'
+ and
+ = link_to 'Code of Conduct', 'https://fnf.page.link/coc'
+ and are responsible for sharing these documents with your guests. You
+ further understand that you are responsible for the conduct of your guests
+ while they attend an FnF event. By making clear the values that inform our
+ events and setting the expectation of conduct at our events, we hope to
+ continue to embrace radical self-expression while continuing to invite new
+ and diverse people into our community.
- .actions
- = f.submit 'Pay Now', class: 'btn btn-primary btn-large'
+ .actions
+ = f.submit 'Pay Now', class: 'btn btn-primary btn-large'
- %span.text-error#stripe-error
- %noscript
- JavaScript is not enabled and is required for this form. Enable it in
- your web browser settings and refresh the page to continue.
+ %span.text-error#stripe-error
+ %noscript
+ JavaScript is not enabled and is required for this form. Enable it in
+ your web browser settings and refresh the page to continue.
diff --git a/app/views/payments/new.html.haml b/app/views/payments/new.html.haml
index 5d7ac7ce..a6422deb 100644
--- a/app/views/payments/new.html.haml
+++ b/app/views/payments/new.html.haml
@@ -1,33 +1,37 @@
- content_for(:meta) do
- %meta{ name: 'stripe-key', content: STRIPE_PUBLIC_KEY }
+ %meta{ name: 'stripe-key', content: Rails.application.credentials.send(Rails.env.to_sym).stripe.publishable_api_key }
- content_for(:head) do
- = javascript_include_tag 'https://js.stripe.com/v1/'
+ = javascript_include_tag 'https://js.stripe.com/v3/'
-%p.lead
- Hi #{@user.first_name},
+.content-fluid
+ .row
+ .col-4
+ .card
+ .card-header.bg-secondary-subtle
+ %h3
+ Hi, #{@user.first_name}
--# HACK: Temporarily hide this for Mo's event
-- if @event.tickets_require_approval
- %p.lead.text-success
- Your request for
- %b
- = @ticket_request.adults
- = 'ticket'.pluralize(@ticket_request.adults)
- has been approved!
- %p
- Now all that's left is to pay for your tickets.
- If you are paying via credit card, fill out the form below.
- %br
- = link_to 'I am not paying via credit card',
- other_payments_path(ticket_request_id: @ticket_request.id)
+ .card-body
+ - if @event.tickets_require_approval
+ %p.lead.text-success
+ Your request for
+ %b
+ = @ticket_request.adults
+ = 'ticket'.pluralize(@ticket_request.total_tickets)
+ has been approved!
+ %p
+ Now all that's left is to pay for your tickets.
+ If you are paying via credit card, fill out the form below.
+ %br
+ = link_to 'I am not paying via credit card',
+ other_payments_path(ticket_request_id: @ticket_request.id)
-- else
- %p.lead.text-success
- You're almost done! All that's left is to purchase your
- = succeed '.' do
- = 'ticket'.pluralize(@ticket_request.total_tickets)
+ - else
+ %p.lead.text-success
+ You're almost done! All that's left is to purchase your
+ = succeed '.' do
+ = 'ticket'.pluralize(@ticket_request.total_tickets)
-%hr
-
-= render 'form'
+ .col-8
+ = render 'form'
diff --git a/app/views/ticket_request_mailer/request_received.html.haml b/app/views/ticket_request_mailer/request_received.html.haml
index b90296af..558778df 100644
--- a/app/views/ticket_request_mailer/request_received.html.haml
+++ b/app/views/ticket_request_mailer/request_received.html.haml
@@ -2,13 +2,8 @@
Hi #{@ticket_request.user.first_name},
%p
- We have received your ticket request for #{@event.name}.
-
--# TODO: This is temporary until tickets stop selling
--#- if @ticket_request.role == 'volunteer'
--# %p
--# At this point, all available tickets have been requested. However,
--# we'll hold on to your request just in case.
+ We have received your ticket request for #{@event.name} for
+ #{@ticket_request.total_tickets} total tickets (including kids).
%p
If your request is approved, we will send you confirmation of the approved
@@ -20,12 +15,10 @@
patience.
%p
- With love,
+ With love ❤️,
%br
Your FnF Ticket Team
%p
- P.S. You can see the status of your request at any time by
- visiting
- = succeed '.' do
- = link_to 'this page', @ticket_request_url
+ P.S. You can view sthe status of your request at any time by visiting
+ = link_to 'this page', @ticket_request_url
diff --git a/app/views/ticket_requests/_form.html.haml b/app/views/ticket_requests/_form.html.haml
index 2ec874ff..c30b75e6 100644
--- a/app/views/ticket_requests/_form.html.haml
+++ b/app/views/ticket_requests/_form.html.haml
@@ -120,9 +120,9 @@
%span.help-inline.inline-price
%p.help-inline-block.muted
Please include the ages of the children (including infants) you are
- bringing with you in the notes below.
+ bringing with you in the notes at the bottom of this form.
- - if @event.cabin_price
+ -# - if false @event.cabin_price
= f.label :cabins do
How many cabins did you want?
@@ -169,6 +169,9 @@
= f.label :notes do
Who did you hear about this event from?
Any special requests or things you want to mention?
+ %br
+ .text-success
+ Bringing children? Please list their names and ages here.
= f.text_area :notes,
rows: 4, columns: 100, maxlength: 500, style: 'width: 100%'
@@ -179,8 +182,8 @@
Additional Notes
%p.text-error
Visible by event admins only.
- = f.text_area :admin_notes, rows: 5, maxlength: 512
-
+ = f.text_area :admin_notes, rows: 5, columns: 800, maxlength: 512, style: 'width: 100%'
+ %br
%hr
- unless is_update
@@ -191,41 +194,50 @@
= f.label :agrees_to_terms, class: 'checkbox' do
= f.check_box :agrees_to_terms
I’ve read
- = link_to 'The FnF Way', 'http://cfaea.net/the-fnf-way/', target: '_blank'
+ = link_to 'The FnF Way', 'http://cfaea.net/the-fnf-way/', target: '_blank', onclick: "popupWindow('http://cfaea.net/the-fnf-way/', 'The FnF Way', window, 700, 900); return false;"
and
- = link_to 'Code of Conduct', 'https://fnf.page.link/coc', target: '_blank'
+ = link_to 'Code of Conduct', 'https://fnf.page.link/coc', target: '_blank', onclick: "popupWindow('https://fnf.page.link/coc', 'Code of Conduct', window, 800, 900); return false;"
and agree to follow the principles outlined therein
%br
- if is_update
+ %p
.control-group
%h4 Guests
%p
- Include yourself as a guest. Use First Name and Last Name.
+ Include yourself as a guest.
+ %p
+ %strong
+ Use First Name and Last Name and Email within angle brackets.
+ %p
DJ names or monikers should be accompanied with their real name.
+ %p
If we cannot identify the name, we will ask you to change it.
- %b Examples of good names
- %ol
- %li Tim Bergling
- %li Tim Bergling (Avicii)
- %b Examples of bad names
+ %p.text-success
+ %b Examples of good names
%ol
- %li Tim
- %li Bergling
- %li T. B.
- %br
- - list_finalized = (@event.start_time - Time.now) < 2.days
+ %li Carl Cox (self) <carl@carlcox.com>
+ %li John Digweed <digweed@bedrock-records.com>
+
+ - list_finalized = (@event.start_time - Time.current) < ::Event::GUEST_LIST_FINAL_WITHIN
- if list_finalized
- Guest list has been finalized. If you need to update your guests, please email
- = mail_to 'tickets@fnf.org'
- %br
- - @ticket_request.guest_count.times do |guest_id|
- = f.text_field :guests, readonly: list_finalized, multiple: true, value: Array(@ticket_request.guests)[guest_id]
+ %span.text-error
+ Guest list has already been finalized. If you need to update your guests, please email
+ = mail_to 'tickets@fnf.org'
%br
+ - else
+ - @ticket_request.guest_count.times do |guest_id|
+ = f.label "Guest #{guest_id + 1}"
+ - default_value = guest_id == 0 ? @ticket_request.user.name_and_email : ''
+ = f.text_field :guest_list, readonly: list_finalized, multiple: true, value: Array(@ticket_request.guests)[guest_id] || default_value, style: 'width: 80%'
+ %br
.actions
- submit_btn_text = is_update ? 'Update Request' : 'Submit Request'
= f.submit submit_btn_text, class: 'btn btn-primary btn-large', disabled: !is_update,
id: 'submit-request',
data: { disable_with: 'Submitting...' }
+ = link_to event_ticket_request_path(@event, @ticket_request), class: 'btn' do
+ %i.icon-arrow-left
+ Back
diff --git a/app/views/ticket_requests/edit.html.haml b/app/views/ticket_requests/edit.html.haml
index 20f32c20..582954ca 100644
--- a/app/views/ticket_requests/edit.html.haml
+++ b/app/views/ticket_requests/edit.html.haml
@@ -1,6 +1,3 @@
= render 'form'
-= link_to event_ticket_request_path(@event, @ticket_request), class: 'btn' do
- %i.icon-arrow-left
- Back
diff --git a/app/views/ticket_requests/index.html.haml b/app/views/ticket_requests/index.html.haml
index f1061e27..32a25adc 100644
--- a/app/views/ticket_requests/index.html.haml
+++ b/app/views/ticket_requests/index.html.haml
@@ -112,15 +112,13 @@
class: 'hover-tooltip',
title: 'User has requested a car/RV camping spot because: ' + ticket_request.car_camping_explanation)
- if ticket_request.needs_assistance
- = image_tag('bank.png', width: 16, class: 'hover-tooltip',
- title: 'User has requested financial assistance')
+ = image_tag('bank.png', width: 16, class: 'hover-tooltip', title: 'User has requested financial assistance')
- if ticket_request.notes.present?
%i.icon-comment.hover-tooltip{ title: 'Additional requests or comments: ' + ticket_request.notes }
+
%td= ticket_request.adults
- if @event.kid_ticket_price
%td= ticket_request.kids
- - if @event.cabin_price
- %td= ticket_request.cabins
- if @event.eald?
%td
#{ticket_request.early_arrival_passes} / #{ticket_request.late_departure_passes}
@@ -142,12 +140,12 @@
%td
- if @event.tickets_require_approval && ticket_request.pending?
.btn-group.pull-right
- = link_to approve_event_ticket_request_path(@event, ticket_request),
+ = button_to approve_event_ticket_request_path(@event, ticket_request),
method: :post,
class: 'btn btn-primary' do
Approve
%i.icon-ok
- = link_to decline_event_ticket_request_path(@event, ticket_request),
+ = button_to decline_event_ticket_request_path(@event, ticket_request),
method: :post,
class: 'btn btn-danger',
data: { confirm: "Are you sure you want to decline #{ticket_request.user.name}'s request?" } do
@@ -156,17 +154,17 @@
- elsif !ticket_request.payment
.btn-group.pull-right
- if ticket_request.declined?
- = link_to revert_to_pending_event_ticket_request_path(@event, ticket_request),
+ = button_to revert_to_pending_event_ticket_request_path(@event, ticket_request),
method: :post,
class: 'btn btn-link' do
%span.hover-tooltip{ title: 'Reset status of request to Pending', data: { placement: 'left' } }
Revert
- elsif !ticket_request.completed?
- = link_to resend_approval_event_ticket_request_path(@event, ticket_request),
+ = button_to resend_approval_event_ticket_request_path(@event, ticket_request),
method: :post,
class: 'btn btn-link' do
Resend Approval
- = link_to decline_event_ticket_request_path(@event, ticket_request),
+ = button_to decline_event_ticket_request_path(@event, ticket_request),
method: :post,
class: 'btn btn-link',
data: { confirm: "Are you sure you want to decline #{ticket_request.user.name}'s already approved request?" } do
@@ -174,7 +172,7 @@
- elsif ticket_request.payment && !ticket_request.payment.received?
.btn-group.pull-right
- = link_to mark_received_payments_path(ticket_request_id: ticket_request),
+ = button_to mark_received_payments_path(ticket_request_id: ticket_request),
method: :post,
class: 'btn btn-primary' do
Mark Payment Received
diff --git a/app/views/ticket_requests/show.html.haml b/app/views/ticket_requests/show.html.haml
index 6f164421..98d53cb3 100644
--- a/app/views/ticket_requests/show.html.haml
+++ b/app/views/ticket_requests/show.html.haml
@@ -1,11 +1,17 @@
.card
- .card-header
+ .card-header.bg-success-subtle
+ = content_for(:title, "#{@event.name} — Ticket Request")
+ %h3= @event.name
%h2
- = content_for(:title, "#{@event.name} — Ticket Request")
.card-body
%p.lead
+ %h4
+ Status:
+ = @ticket_request.status_name
+
- if @ticket_request.user == current_user
+
- if @ticket_request.pending?
%p.lead
Thanks for requesting a ticket!
@@ -34,12 +40,12 @@
= text_for_status @ticket_request
- if @event.admin?(current_user) && @ticket_request.pending?
.btn-group
- = link_to approve_event_ticket_request_path(@event, @ticket_request),
+ = button_to approve_event_ticket_request_path(@event, @ticket_request),
method: :post,
class: 'btn btn-primary btn-mini' do
Approve
%i.icon-ok
- = link_to decline_event_ticket_request_path(@event, @ticket_request),
+ = button_to decline_event_ticket_request_path(@event, @ticket_request),
method: :post,
class: 'btn btn-danger btn-mini',
data: { confirm: "Are you sure you want to decline #{@ticket_request.user.name}'s request?" } do
@@ -66,7 +72,7 @@
Not yet received
- if @event.ticket_sales_open?
= link_to @ticket_request.all_guests_specified? ? 'Purchase your ticket now' : 'All guests must be filled out before purchasing ticket',
- new_payment_path(ticket_request_id: @ticket_request),
+ new_payment_path(ticket_request_id: @ticket_request.id),
class: 'btn btn-small btn-primary'
- else
%span.text-warning
diff --git a/config/credentials.yml.enc b/config/credentials.yml.enc
index a96d78a3..fd549e59 100644
--- a/config/credentials.yml.enc
+++ b/config/credentials.yml.enc
@@ -1 +1 @@
-ZWWtVk+4GEPw3cFJG9I/GJW/IhdcKOuVZEr+NidRlym90tgBBT7hTvUMvF9sj28vCVLRT2BdF/XquhkJPwa/WpgifyPRoP3Ch5hMj0LdCKtfFSRsueQGDB8N4J6cCAuOgW96kBHFjCQ5lO3pBhf19CoaZz7IvhUr0bIy5vnhyma7HdVDshAlvOAbMYv++Ua1wqqtzWp7mb20k+n3lAsIsWLSPVpZ+U0/WN2h6oGrgX8gZB81RhnzQh7KUL4Yw/qQkttPrVNam/dWc0l2WYsjWlGUd/k8xNyZQ+8BkisfreDJGvwrwTkxvyDvKAckC9yudpNTSDKFH3EWx3SOL670lNTzK3kyMRqyFod9BDtP8Oxl3MPUyvvGZOVNfqm/+cMgEQPNmYTMO9mI8mvKPuRXSiSGG8N0/j/d/xmXJPBCP3LioTT8ndEtQMSU7i6Di6+9WPrjwyO/oUsPU0AueP1Lz1P2FoyEdUELOusyekJqfPJAqkyGdoHCWjyJSj/MknDIXDNTUOM2wfS0yaXDg+cKV+QecmScwV2ES+kuTuNGEIxqCYSamWwjPE7Q52EQeM+KejWAr90Wo+PxsmHCERHO4vWise2Mi8z7wKZIJn8mhSOt/Rmu1iqJmZkqwWaIeG8uAhjw6L4w2AEV+8N7kleJogmjXRBLI7K/4tPRvL2hqgIYdLbMmHYyEGjgYEFTIiUGakKovf9ygF3JrmJ5s3IOGrIbrpBQ4/yE1oXy2JiTqad4rfPAy6mP/2imhwk6u1XemdrhZalm/GQ4h6l5AufTU5b77zvg66WHMDybzY4hFQ8PdzkQmo9xsUnbiEvzACnhoyJHCEQOqDHMdAnl+7EyRM4xZnIlOTkYEbu+Ah2u44g9+svG5xcE6bZ2L43DhUDZNmjmEn+DmjCXjMP8AGRGNbRplEnr5MluD93SrFL0V3ZbwlSFDJZXWi93DVeHYmURnvDUp8I4aqHkTwg759UUzUVHVcCnJ2kb0VQvWfPOBjIHCUaQwe/OLRtQMotkEUnD8N6OPOH7tX498hUNheoA2s/Wsjxz9IX0xBISoa6lwVJ+NnX4evwtEtNeiZzoathvBs91eTDCV9s5OLlCMjt/az+0+umUxK/XcZsvFEBUGA==--66+ryGVyib21rESb--zV4MhpvtIzu6kgxB9cfr6g==
\ No newline at end of file
+2XLBmLmeTOdjIMwsLiejhc6pBH4n9XOnXgkAr4Fxu7HhU5s0oh4nkNCOznFbzBcmDHRyQKmYKmKL+h6UrJFk4WTRAFVx2EsEXWlX2OFriJUj+hEfuGGpnqAmyJFgx2K/N3B1rSvcM66E/ZTlBrFkR1M3QxPRxtoLVl7iEsqsPdEz2iBe1TNHCqo8XW/58K2ZTrkRKLv/07jOAw3PB1ufnv3SkiXIz4fZIWz0zAb1W/p/VocHk6vonfrvarlKTI3epv7XjvFVuFsPzIQOx8by8fn/ukH9kjWxsC/dqsAkFAkSEYnxro3cc+NjazMcOX9PdFmF92QzfUDplP9Yw9CedC/9eshaKmeOcjw5VvmGX2588ClLJyCIuIHg/v8gYQGtX9ibttKliK5Mu3e4AzgVlAxLMrk/I8jM3Riiu3WYg0m5V57/3ChUFlu1+6dvwpmQHupVkZOYwqhY8rqptF76OeYvChgSqc751KHFcHrCMJMAiVlifWV4C2uJonHQ1t2ygvbktRvWgyvvaSIX1YyTKc9Mh8AmqXuQ5W7840orf0eK86BTvTCPtOf8eY4HBQw3TlhGytXoJQxcGe26N7tbJxRuApPXqSZ/kfzSz0YAd3kAByOuvJiQXLWOCRtwmT6/HZNIb/MewsUS0Lce7birWCjZLUIINt4BSdfRdP/YOry0g6ZDY0LqogYHQHQeRDxW2ZfmrLpD3EvG7OtP2qxRdQz72iNxDThuG0n3quaeL+SDLswgKwyXBOFMiyMaXu/QHeDaCG57PfAZ8TK2L4+bnlo7uXpCALYyCQnXibdoE7UY+SlitnetIMylbPsivIWwwt/N0G1vRVLh9W2eM3MU13ZgLIiLDATu6wrl6dMdeH1Ou+GcIg5LL8Vr8tqW5lKbqyQ76LOXwGjcu/coUdl+XWEUdONT8SHGtMgVoNCXZ5gqjXbrNq9beHjdaWMW5lSC1OJGJOxFsQfd0wdAHssrW84zX3WDap/Xy2pETLmg1rdXLwIDWrro8CSG4QMd66C3gKp/57zoKdwvEvPo5Q9MPWP8ReMpCNrqHmGvtOadLDf/pXYJ8EYdfWWE9uX1H8+VMlfCkCPQZFjncUc5YDhWJaMrE/y1ObEajH/0NyQOK0dd+AL5ePWV/Dn74UuVZwI6y+fVXc/H4OufrIqu1/F0HrULSYyafbh6M61Kf8U58A/3pRBD4DxsvjVFC+JtStiQcvEbGlepKaGli2JjBNfanEhWX7NnAtgOfTR6MdEXQ1csfSm2jvmRtUaQD33XO0bGkIqJrs4BhR3UJtFv03s6Xo4/MNVCjsz69L93LlBJy8g3eQjx/lnT7nKqerUlNYiPl9XyRy847SZ0bJtVE2pEnMhGQfXU7IirDWuqp519CjnrsFczx43PF1UXX5tPzD5jPRtwQLpqYpOep4YVeNW8QrZHVT7JFDL6K6GcVcaayO1vvJxDHvcpmOo76lJvwYZcrwirnCiCaA==--d+Ssl/BD+QJEGJdg--XqpQpUWm3fiRgcNNDgvPWg==
\ No newline at end of file
diff --git a/config/environments/development.rb b/config/environments/development.rb
index e8bc563b..78325c12 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -22,14 +22,14 @@
# Enable/disable caching. By default caching is disabled.
# Run rails dev:cache to toggle caching.
if Rails.root.join('tmp/caching-dev.txt').exist?
- config.action_controller.perform_caching = true
+ config.action_controller.perform_caching = true
config.action_controller.enable_fragment_cache_logging = true
- config.cache_store = :memory_store
+ config.cache_store = :memory_store
config.public_file_server.headers = { 'Cache-Control' => "public, max-age=#{2.days.to_i}" }
else
config.action_controller.perform_caching = false
- config.cache_store = :null_store
+ config.cache_store = :null_store
end
config.public_file_server.enabled = true
@@ -75,23 +75,39 @@
# Apply autocorrection by RuboCop to files generated by `bin/rails generate`.
config.generators.apply_rubocop_autocorrect_after_generate!
- config.action_mailer.default_url_options = { host: 'localhost:8080' }
+ config.action_mailer.default_url_options = { host: 'tickets-local.fnf.org:8080' }
config.action_mailer.raise_delivery_errors = true
- config.action_mailer.delivery_method = :smtp
+ config.action_mailer.delivery_method = :smtp
+
+ # # noinspection RubyResolve
+ # config.action_mailer.smtp_settings = {
+ # address: 'smtp.gmail.com',
+ # port: 587,
+ # domain: Rails.application.credentials.development.gmail.domain,
+ # user_name: Rails.application.credentials.development.gmail.user_name,
+ # password: Rails.application.credentials.development.gmail.password, # https://myaccount.google.com/apppasswords
+ # authentication: 'plain',
+ # enable_starttls_auto: true,
+ # open_timeout: 10,
+ # read_timeout: 10
+ # }
+
# noinspection RubyResolve
config.action_mailer.smtp_settings = {
- address: 'smtp.gmail.com',
+ address: 'smtp.sendgrid.net',
+ user_name: 'apikey',
port: 587,
- domain: Rails.application.credentials.development.gmail.domain,
- user_name: Rails.application.credentials.development.gmail.user_name,
- password: Rails.application.credentials.development.gmail.password, # https://myaccount.google.com/apppasswords
- authentication: 'plain',
+ domain: Rails.application.credentials.development.sendgrid.domain,
+ password: Rails.application.credentials.development.sendgrid.api_key,
+ authentication: :plain,
enable_starttls_auto: true
}
config.hosts = %w[localhost 127.0.0.1 127.0.0.1:3000 127.0.0.1:8080 0.0.0.0:8080]
config.hosts << 'tickets-local.fnf.org:8080'
- config.log_tags = [:request_id]
+ config.log_tags = [:request_id]
config.log_level = :debug
+
+ config.web_console.permissions = '172.16.100.0/24'
end
diff --git a/package.json b/package.json
index e4b6a8de..82c31a94 100644
--- a/package.json
+++ b/package.json
@@ -62,7 +62,7 @@
},
"volta": {
"node": "20.12.2",
- "yarn": "4.1.1"
+ "yarn": "4.2.1"
},
"babel": {
"presets": [
diff --git a/spec/controllers/ticket_requests_controller_spec.rb b/spec/controllers/ticket_requests_controller_spec.rb
index 792dc899..6bf554de 100644
--- a/spec/controllers/ticket_requests_controller_spec.rb
+++ b/spec/controllers/ticket_requests_controller_spec.rb
@@ -79,7 +79,7 @@
describe 'GET #new' do
let(:event) { create(:event) }
- before { get :new, params: { event_id: event } }
+ subject { get :new, params: { event_id: event.id } }
context 'when viewer not signed in' do
it { succeeds }