diff --git a/.rubocop.yml b/.rubocop.yml index 3384ae48..3c1b0b43 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -19,6 +19,9 @@ RSpecRails/InferredSpecType: Metrics/ClassLength: Max: 300 +Metrics/ModuleLength: + Enabled: false + Layout/HashAlignment: Enabled: true EnforcedColonStyle: table diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index ab165ff1..f2767cca 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2024-05-20 07:05:31 UTC using RuboCop version 1.63.5. +# on 2024-05-20 17:20:36 UTC using RuboCop version 1.63.5. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -37,11 +37,6 @@ Metrics/CyclomaticComplexity: Metrics/MethodLength: Max: 58 -# Offense count: 1 -# Configuration parameters: CountComments, CountAsOne. -Metrics/ModuleLength: - Max: 112 - # Offense count: 10 # Configuration parameters: AllowedMethods, AllowedPatterns. Metrics/PerceivedComplexity: diff --git a/Gemfile.lock b/Gemfile.lock index 5b80c648..69c65bf9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -91,7 +91,9 @@ GEM awesome_print (1.9.2) base64 (0.2.0) bcrypt (3.1.20) - bcrypt_pbkdf (1.1.0) + bcrypt_pbkdf (1.1.1) + bcrypt_pbkdf (1.1.1-arm64-darwin) + bcrypt_pbkdf (1.1.1-x86_64-darwin) better_errors (2.10.1) erubi (>= 1.0.0) rack (>= 0.9.0) @@ -283,7 +285,7 @@ GEM colorize (~> 0.8) net_http_unix (~> 0.2) parallel (~> 1) - racc (1.7.3) + racc (1.8.0) rack (3.0.11) rack-session (2.0.0) rack (>= 3.0.0) diff --git a/app/assets/images/communications.png b/app/assets/images/home/communications.png similarity index 100% rename from app/assets/images/communications.png rename to app/assets/images/home/communications.png diff --git a/app/assets/images/design-tools.png b/app/assets/images/home/design-tools.png similarity index 100% rename from app/assets/images/design-tools.png rename to app/assets/images/home/design-tools.png diff --git a/app/assets/images/payment-savings.png b/app/assets/images/home/payment-savings.png similarity index 100% rename from app/assets/images/payment-savings.png rename to app/assets/images/home/payment-savings.png diff --git a/app/assets/images/bank.png b/app/assets/images/icons/bank.png similarity index 100% rename from app/assets/images/bank.png rename to app/assets/images/icons/bank.png diff --git a/app/assets/images/car.png b/app/assets/images/icons/car.png similarity index 100% rename from app/assets/images/car.png rename to app/assets/images/icons/car.png diff --git a/app/assets/images/icons/comments-admin.png b/app/assets/images/icons/comments-admin.png new file mode 100644 index 00000000..52912027 Binary files /dev/null and b/app/assets/images/icons/comments-admin.png differ diff --git a/app/assets/images/icons/comments-user.png b/app/assets/images/icons/comments-user.png new file mode 100644 index 00000000..7a840411 Binary files /dev/null and b/app/assets/images/icons/comments-user.png differ diff --git a/app/assets/images/icons/dollar-yellow.png b/app/assets/images/icons/dollar-yellow.png new file mode 100644 index 00000000..8b729850 Binary files /dev/null and b/app/assets/images/icons/dollar-yellow.png differ diff --git a/app/assets/images/icons/dollar.png b/app/assets/images/icons/dollar.png new file mode 100644 index 00000000..1a75decb Binary files /dev/null and b/app/assets/images/icons/dollar.png differ diff --git a/app/assets/images/icons/rv-wide.png b/app/assets/images/icons/rv-wide.png new file mode 100644 index 00000000..1e86a137 Binary files /dev/null and b/app/assets/images/icons/rv-wide.png differ diff --git a/app/assets/images/rv.png b/app/assets/images/icons/rv.png similarity index 100% rename from app/assets/images/rv.png rename to app/assets/images/icons/rv.png diff --git a/app/assets/stylesheets/site/global.css.scss b/app/assets/stylesheets/site/global.css.scss index a27adb03..f2b40b68 100644 --- a/app/assets/stylesheets/site/global.css.scss +++ b/app/assets/stylesheets/site/global.css.scss @@ -175,3 +175,7 @@ body { #footer-text { margin: 20px 0; } + +img.hover-tooltip { + cursor: pointer; +} diff --git a/app/helpers/ticket_requests_helper.rb b/app/helpers/ticket_requests_helper.rb index c66c281e..b915c648 100644 --- a/app/helpers/ticket_requests_helper.rb +++ b/app/helpers/ticket_requests_helper.rb @@ -12,7 +12,9 @@ def class_for_table_row(ticket_request) def text_class_for_status(ticket_request) case ticket_request.status - when 'P', 'A' + when 'P' + 'bg-warning' + when 'A' 'bg-warning-subtle' when 'D', 'R' 'bg-danger-subtle' diff --git a/app/views/devise/shared/_login.html.haml b/app/views/devise/shared/_login.html.haml index c80ca735..bece5379 100644 --- a/app/views/devise/shared/_login.html.haml +++ b/app/views/devise/shared/_login.html.haml @@ -19,7 +19,7 @@ .row .col-12 - .btn-group-sm - = f.submit "Log in", class: 'btn btn-primary btn-md' + .btn-group-md + = f.submit "Log in", class: 'btn btn-primary btn-lg' = render partial: "devise/shared/links", layout: false, locals: { resource: devise_mapping.singular, resource_name: devise_mapping.name, redirect_to: redirect_to } diff --git a/app/views/devise/shared/_register.html.haml b/app/views/devise/shared/_register.html.haml index 082d5892..e6f8d3c6 100644 --- a/app/views/devise/shared/_register.html.haml +++ b/app/views/devise/shared/_register.html.haml @@ -46,11 +46,7 @@ .row .col-12 - .actions - = f.submit "Register", class: 'btn btn-primary btn-large' - - - .row - .col-12 - = link_to "Go Back ↩".html_safe, :back + .actions.btn-group-md + = f.submit "Register", class: 'btn btn-primary btn-lg' + = link_to "Go Back ↩".html_safe, :back, class: 'btn btn-warning btn-md' diff --git a/app/views/shared/_marketing.html.haml b/app/views/shared/_marketing.html.haml index 92b11bef..56723c09 100644 --- a/app/views/shared/_marketing.html.haml +++ b/app/views/shared/_marketing.html.haml @@ -2,21 +2,21 @@ .container.marketing .row .span4.feature - %img{ src: image_path('design-tools.png') } + %img{ src: image_path('home/design-tools.png') } %h2 Tools %p.lead Use tools specifically designed for organizing community and volunteer-driven events. .span4.feature - %img{ src: image_path('payment-savings.png') } + %img{ src: image_path('home/payment-savings.png') } %h2 Payments %p.lead Accept credit card payments for your event, avoiding more-expensive alternatives like PayPal. .span4.feature - %img{ src: image_path('communications.png') } + %img{ src: image_path('home/communications.png') } %h2 Communications %p.lead diff --git a/app/views/ticket_requests/_table_ticket_request_statuses.html.haml b/app/views/ticket_requests/_table_ticket_request_statuses.html.haml new file mode 100644 index 00000000..33e2855a --- /dev/null +++ b/app/views/ticket_requests/_table_ticket_request_statuses.html.haml @@ -0,0 +1,73 @@ + +.card + .card-header.bg-primary-subtle + .btn-group.mx-4 + = link_to download_event_ticket_requests_path(event), class: 'btn btn-warning ' do + %i.icon-th-list + Download CSV ▼ + .card-body + .vertical-20 + %table.table.border-1.overflow-scroll.w-100 + %thead.border-1.border-dark-subtle + %tr + %th.text-nowrap.bg-dark-subtle.text-left Ticket Status + %th.bg-dark-subtle.text-end.optional-medium Requests + %th.bg-dark-subtle.text-end + Tickets + - if event.kid_ticket_price + %th.bg-dark-subtle.text-end Kids + - if event.cabin_price + %th.bg-dark-subtle.text-end Cabins + %th.bg-dark-subtle.text-end Earn + %tbody + %tr + %td + %span.text-nowrap Paid + %td.text-end.optional-medium + %span= stats[:completed][:requests] + %td.text-end + %span= stats[:completed][:adults] + - if event.kid_ticket_price + %td.text-end + %span= stats[:completed][:kids] + - if event.cabin_price + %td.text-end + %span= stats[:completed][:cabins] + %td.text-end + %span + = number_to_currency(stats[:completed][:raised], precision: 0) + %tr.warning + %td.text-nowrap + Pending Approval + %td.text-end.optional-medium= stats[:pending][:requests] + %td.text-end= stats[:pending][:adults] + - if event.kid_ticket_price + %td.text-end= stats[:pending][:kids] + - if event.cabin_price + %td.text-end= stats[:pending][:cabins] + %td.text-end + %span.muted + = number_to_currency(stats[:pending][:raised], precision: 0) + %tr.success + %td.text-nowrap + Awaiting Payment + %td.text-end.optional-medium= stats[:awaiting_payment][:requests] + %td.text-end= stats[:awaiting_payment][:adults] + - if event.kid_ticket_price + %td.text-end= stats[:awaiting_payment][:kids] + - if event.cabin_price + %td.text-end= stats[:awaiting_payment][:cabins] + %td.text-end + %span.muted + = number_to_currency(stats[:awaiting_payment][:raised], precision: 0) + %tr.muted.border-1.border-dark-subtle + %td.bg-dark-subtle.text-start.fs-6 + %strong + Total + %td.bg-dark-subtle.text-end.optional-medium= stats[:total][:requests] + %td.bg-dark-subtle.text-end.fs-6= stats[:total][:adults] + - if event.kid_ticket_price + %td.bg-dark-subtle.text-end.fs-6= stats[:total][:kids] + - if event.cabin_price + %td.bg-dark-subtle.text-end.fs-6= stats[:total][:cabins] + %td.bg-dark-subtle.text-end.fs-6= number_to_currency(stats[:total][:raised], precision: 0) diff --git a/app/views/ticket_requests/_table_ticket_requests.html.haml b/app/views/ticket_requests/_table_ticket_requests.html.haml new file mode 100644 index 00000000..7563c150 --- /dev/null +++ b/app/views/ticket_requests/_table_ticket_requests.html.haml @@ -0,0 +1,115 @@ + +.card + .card-body.overflow-x-scroll + %table.table + %thead.border-1.border-dark-subtle + %tr + %th.bg-dark-subtle Name + %th.bg-dark-subtle.optional-medium Role + %th.bg-dark-subtle + %th.bg-dark-subtle.text-end.optional-medium Tickets + - if event.kid_ticket_price + %th.bg-dark-subtle.text-end.optional-medium Kids + - if event.cabin_price + %th.bg-dark-subtle.text-end.optional-medium Cabins + - if event.eald? + %th.bg-dark-subtle.text-end.optional-medium EA/LD + %th.bg-dark-subtle.text-end Total + %th.bg-dark-subtle.text-end.optional-medium Date Requested + %th.bg-dark-subtle.text-center Status + %th.bg-dark-subtle.text-end Payment + %tbody + - ticket_requests.each do |ticket_request| + %tr{ class: class_for_table_row(ticket_request) } + %td.align-content-center.ticket-user + = link_to event_ticket_request_path(event, ticket_request) do + = ticket_request.user.name + + %td.muted.align-content-center.optional-medium + = TicketRequest::ROLES[ticket_request.role] + - if ticket_request.role_explanation.present? + %i.icon-comment.hover-tooltip{ title: ticket_request.role_explanation } + + %td.align-content-center + - if ticket_request.admin_notes.present? + = image_tag('icons/comments-admin.png', width: 20, class: 'hover-tooltip', title: "Admin Notes:\n" + ticket_request.admin_notes) + - if ticket_request.car_camping + = image_tag('icons/car.png', width: 20, class: 'hover-tooltip', title: "Car/RV Request:\n" + ticket_request.car_camping_explanation) + - if ticket_request.needs_assistance + = image_tag('icons/dollar.png', width: 20, class: 'hover-tooltip', title: 'Financial Assistance was requested.') + - if ticket_request.notes.present? + = image_tag('icons/comments-user.png', width: 20, class: 'hover-tooltip', title: "User Comments:\n" + ticket_request.notes) + + %td.align-content-center.text-end.optional-medium= ticket_request.adults + + - if event.kid_ticket_price + %td.align-content-center.text-end.optional-medium= ticket_request.kids + + - if event.cabin_price + %td.align-content-center.text-end.optional-medium= ticket_request.cabins + + - if event.eald? + %td.align-content-center.text-end.optional-medium + #{ticket_request.early_arrival_passes} / #{ticket_request.late_departure_passes} + -# %br + -# - if eald_requested?(ticket_request) + -# - if eald_paid?(ticket_request) + -# ✔︎ EALD Paid + -# - else + -# ✘ Not All EALD Bought + -# - else + -# ✘ Not Requested + %td.align-content-center.text-end + %span{ class: ('label label-info' if ticket_request.special_price) } + = number_to_currency(ticket_request.price, precision: 0) + + %td.align-content-center.text-end.optional-medium.text-nowrap.small + = ticket_request.created_at.to_date + + %td.align-content-center.text-center.ticket-status + %span.p-2.rounded.small.bi-credit-card.text-black{ class: text_class_for_status(ticket_request) } + = text_for_status ticket_request + - if ticket_request.payment && !ticket_request.payment.received? + %i.icon-comment.hover-tooltip{ title: ticket_request.payment.explanation } + + %td.align-content-end.text-end + - if event.tickets_require_approval && ticket_request.pending? + .btn-group + = button_to approve_event_ticket_request_path(event, ticket_request), + method: :post, + class: 'btn btn-primary btn-sm text-nowrap' do + ✔︎ Approve + = button_to decline_event_ticket_request_path(event, ticket_request), + method: :post, + class: 'btn btn-danger btn-sm text-nowrap', + data: { confirm: "Are you sure you want to decline #{ticket_request.user.name}'s request?" } do + ✘ Decline + - elsif !ticket_request.payment + .btn-group + - if ticket_request.declined? + = button_to revert_to_pending_event_ticket_request_path(event, ticket_request), + method: :post, + class: 'btn btn-danger btn-sm text-nowrap' do + ↩︎ Revert + - elsif !ticket_request.completed? + = button_to resend_approval_event_ticket_request_path(event, ticket_request), + method: :post, + class: 'btn btn-primary btn-sm text-nowrap' do + ↺ Re-Approve + = button_to manual_confirmation_event_ticket_request_payments_path(event, ticket_request), + method: :post, + class: 'btn btn-success btn-sm text-nowrap' do + $ Received + = button_to decline_event_ticket_request_path(event, ticket_request), + method: :post, + class: 'btn btn-danger btn-sm text-nowrap', + data: { confirm: "Are you sure you want to decline #{ticket_request.user.name}'s already approved request?" } do + ✘ Decline + + - elsif ticket_request.payment && ticket_request.awaiting_payment? && !ticket_request.payment_received? + .btn-group.pull-right + = button_to manual_confirmation_event_ticket_request_payments_path(event, ticket_request), + method: :post, + class: 'btn btn-primary btn-sm ' do + Mark as Received + %i.icon-ok diff --git a/app/views/ticket_requests/index.html.haml b/app/views/ticket_requests/index.html.haml index 4ca1bde1..5649c930 100644 --- a/app/views/ticket_requests/index.html.haml +++ b/app/views/ticket_requests/index.html.haml @@ -1,196 +1,4 @@ = render partial: 'shared/nav_event', locals: { event: @event, active_tab: { ticket_requests: 'active' } } += render partial: 'table_ticket_request_statuses', locals: { event: @event, stats: @stats } += render partial: 'table_ticket_requests', locals: { event: @event, ticket_requests: @ticket_requests } -.card - .card-header.bg-primary-subtle - .btn-group.mx-4 - = link_to download_event_ticket_requests_path(@event), class: 'btn btn-warning ' do - %i.icon-th-list - Download CSV ▼ - .card-body.overflow-scroll.w-100 - .vertical-20 - %table.table.border-1 - %thead.border-1.border-dark-subtle - %tr - %th.text-nowrap.bg-dark-subtle.text-left Ticket Status - %th.bg-dark-subtle.text-end.optional-medium Requests - %th.bg-dark-subtle.text-end - Tickets - - if @event.kid_ticket_price - %th.bg-dark-subtle.text-end Kids - - if @event.cabin_price - %th.bg-dark-subtle.text-end Cabins - %th.bg-dark-subtle.text-end Earn - %tbody - %tr - %td - %span.text-nowrap Paid - %td.text-end.optional-medium - %span= @stats[:completed][:requests] - %td.text-end - %span= @stats[:completed][:adults] - - if @event.kid_ticket_price - %td.text-end - %span= @stats[:completed][:kids] - - if @event.cabin_price - %td.text-end - %span= @stats[:completed][:cabins] - %td.text-end - %span - = number_to_currency(@stats[:completed][:raised], precision: 0) - %tr.warning - %td.text-nowrap - Pending Approval - %td.text-end.optional-medium= @stats[:pending][:requests] - %td.text-end= @stats[:pending][:adults] - - if @event.kid_ticket_price - %td.text-end= @stats[:pending][:kids] - - if @event.cabin_price - %td.text-end= @stats[:pending][:cabins] - %td.text-end - %span.muted - = number_to_currency(@stats[:pending][:raised], precision: 0) - %tr.success - %td.text-nowrap - Awaiting Payment - %td.text-end.optional-medium= @stats[:awaiting_payment][:requests] - %td.text-end= @stats[:awaiting_payment][:adults] - - if @event.kid_ticket_price - %td.text-end= @stats[:awaiting_payment][:kids] - - if @event.cabin_price - %td.text-end= @stats[:awaiting_payment][:cabins] - %td.text-end - %span.muted - = number_to_currency(@stats[:awaiting_payment][:raised], precision: 0) - %tr.muted.border-1.border-dark-subtle - %td.bg-dark-subtle.text-start.fs-6 - %strong - Total - %td.bg-dark-subtle.text-end.optional-medium= @stats[:total][:requests] - %td.bg-dark-subtle.text-end.fs-6= @stats[:total][:adults] - - if @event.kid_ticket_price - %td.bg-dark-subtle.text-end.fs-6= @stats[:total][:kids] - - if @event.cabin_price - %td.bg-dark-subtle.text-end.fs-6= @stats[:total][:cabins] - %td.bg-dark-subtle.text-end.fs-6= number_to_currency(@stats[:total][:raised], precision: 0) - - .vertical-20 - %hr - .vertical-20 - -.card - .card-body.overflow-scroll.w-100 - %table.table - %thead.border-1.border-dark-subtle - %tr - %th.bg-dark-subtle Name - %th.bg-dark-subtle.optional-medium Role - %th.bg-dark-subtle.optional-medium - %th.bg-dark-subtle.text-end.optional-medium Tickets - - if @event.kid_ticket_price - %th.bg-dark-subtle.text-end.optional-medium Kids - - if @event.cabin_price - %th.bg-dark-subtle.text-end.optional-medium Cabins - - if @event.eald? - %th.bg-dark-subtle.text-end.optional-medium EA/LD - %th.bg-dark-subtle.text-end Total - %th.bg-dark-subtle.text-end.optional-medium Date Requested - %th.bg-dark-subtle.text-center Status - %th.bg-dark-subtle.text-end Payment - %tbody - - @ticket_requests.each do |ticket_request| - %tr{ class: class_for_table_row(ticket_request) } - %td.align-content-center.ticket-user - = link_to event_ticket_request_path(@event, ticket_request) do - = ticket_request.user.name - - %td.muted.align-content-center.optional-medium - = TicketRequest::ROLES[ticket_request.role] - - if ticket_request.role_explanation.present? - %i.icon-comment.hover-tooltip{ title: ticket_request.role_explanation } - - %td.align-content-center.optional-medium - - if ticket_request.admin_notes.present? - %i.icon-asterisk.hover-tooltip{ title: 'Ticket Coordinator Notes: ' + ticket_request.admin_notes } - - if ticket_request.car_camping - = image_tag('car.png', - width: 16, - 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') - - if ticket_request.notes.present? - %i.icon-comment.hover-tooltip{ title: 'Additional requests or comments: ' + ticket_request.notes } - - %td.align-content-center.text-end.optional-medium= ticket_request.adults - - - if @event.kid_ticket_price - %td.align-content-center.text-end.optional-medium= ticket_request.kids - - - if @event.cabin_price - %td.align-content-center.text-end.optional-medium= ticket_request.cabins - - - if @event.eald? - %td.align-content-center.text-end.optional-medium - #{ticket_request.early_arrival_passes} / #{ticket_request.late_departure_passes} - -# %br - -# - if eald_requested?(ticket_request) - -# - if eald_paid?(ticket_request) - -# ✔︎ EALD Paid - -# - else - -# ✘ Not All EALD Bought - -# - else - -# ✘ Not Requested - %td.align-content-center.text-end - %span{ class: ('label label-info' if ticket_request.special_price) } - = number_to_currency(ticket_request.price, precision: 0) - - %td.align-content-center.text-end.optional-medium.text-nowrap.small - = ticket_request.created_at.to_date - - %td.align-content-center.text-center.ticket-status - %span.p-2.rounded.small.bi-credit-card.text-black{ class: text_class_for_status(ticket_request) } - = text_for_status ticket_request - - if ticket_request.payment && !ticket_request.payment.received? - %i.icon-comment.hover-tooltip{ title: ticket_request.payment.explanation } - - %td.align-content-end.text-end - - if @event.tickets_require_approval && ticket_request.pending? - .btn-group - = button_to approve_event_ticket_request_path(@event, ticket_request), - method: :post, - class: 'btn btn-primary btn-sm text-nowrap' do - ✔︎ Approve - = button_to decline_event_ticket_request_path(@event, ticket_request), - method: :post, - class: 'btn btn-danger btn-sm text-nowrap', - data: { confirm: "Are you sure you want to decline #{ticket_request.user.name}'s request?" } do - ✘ Decline - - elsif !ticket_request.payment - .btn-group - - if ticket_request.declined? - = button_to revert_to_pending_event_ticket_request_path(@event, ticket_request), - method: :post, - class: 'btn btn-danger btn-sm text-nowrap' do - ↩︎ Revert - - elsif !ticket_request.completed? - = button_to resend_approval_event_ticket_request_path(@event, ticket_request), - method: :post, - class: 'btn btn-primary btn-sm text-nowrap' do - ↺ Re-Approve - = button_to manual_confirmation_event_ticket_request_payments_path(@event, ticket_request), - method: :post, - class: 'btn btn-success btn-sm text-nowrap' do - $ Received - = button_to decline_event_ticket_request_path(@event, ticket_request), - method: :post, - class: 'btn btn-danger btn-sm text-nowrap', - data: { confirm: "Are you sure you want to decline #{ticket_request.user.name}'s already approved request?" } do - ✘ Decline - - - elsif ticket_request.payment && ticket_request.awaiting_payment? && !ticket_request.payment_received? - .btn-group.pull-right - = button_to manual_confirmation_event_ticket_request_payments_path(@event, ticket_request), - method: :post, - class: 'btn btn-primary btn-sm ' do - Mark as Received - %i.icon-ok