From 02c5cfab61a336833e02abcba6dd38b479a7446f Mon Sep 17 00:00:00 2001 From: moveson Date: Mon, 16 Dec 2024 10:47:52 -0700 Subject: [PATCH 01/10] Show status table only if form has been uploaded --- .../_service_form_status_card.html.erb | 66 +++++++++---------- .../_lottery_entrant_with_tickets.html.erb | 3 +- 2 files changed, 33 insertions(+), 36 deletions(-) diff --git a/app/views/lotteries/entrant_service_details/_service_form_status_card.html.erb b/app/views/lotteries/entrant_service_details/_service_form_status_card.html.erb index 2f458f9bd..208d9f1af 100644 --- a/app/views/lotteries/entrant_service_details/_service_form_status_card.html.erb +++ b/app/views/lotteries/entrant_service_details/_service_form_status_card.html.erb @@ -11,40 +11,36 @@ -
- - - - - - - - - - <% if presenter.rejected? %> - - - - - <% elsif presenter.accepted? %> + <% if presenter.completed_form.attached? %> +
+
- <% if presenter.completed_form.attached? %> - <%= fa_icon("circle-check", type: :solid, class: "text-success") %> - <% else %> - <%= fa_icon("circle-minus", type: :regular, class: "text-warning") %> - <% end %> - <%= presenter.completed_form.attached? ? "Uploaded" : "No file uploaded" %><%= l(presenter.completed_form.created_at) if presenter.completed_form.attached? %><%= presenter.completed_form.filename %>
<%= fa_icon("circle-xmark", type: :solid, class: "text-danger") %>Rejected<%= l(presenter.service_form_rejected_at) %><%= presenter.service_form_rejected_comments %>
+ + - - - - <% elsif presenter.completed_form.attached? %> - - - - - <% end %> - - -
<%= fa_icon("circle-check", type: :solid, class: "text-success") %>Accepted<%= l(presenter.service_form_accepted_at) %><%= presenter.service_form_accepted_comments %><%= fa_icon("file-magnifying-glass", type: :solid, class: "text-secondary") %>Under review
-
+ Uploaded + <%= l(presenter.completed_form.created_at) %> + <%= presenter.completed_form.filename %> + + + <% if presenter.rejected? %> + <%= fa_icon("circle-xmark", type: :solid, class: "text-danger") %> + Rejected + <%= l(presenter.service_form_rejected_at) %> + <%= presenter.service_form_rejected_comments %> + <% elsif presenter.accepted? %> + <%= fa_icon("circle-check", type: :solid, class: "text-success") %> + Accepted + <%= l(presenter.service_form_accepted_at) %> + <%= presenter.service_form_accepted_comments %> + <% elsif presenter.completed_form.attached? %> + <%= fa_icon("file-magnifying-glass", type: :solid, class: "text-secondary") %> + Under review + + + <% end %> + + + + + <% end %> diff --git a/app/views/lottery_entrants/_lottery_entrant_with_tickets.html.erb b/app/views/lottery_entrants/_lottery_entrant_with_tickets.html.erb index 3932f7987..e494121db 100644 --- a/app/views/lottery_entrants/_lottery_entrant_with_tickets.html.erb +++ b/app/views/lottery_entrants/_lottery_entrant_with_tickets.html.erb @@ -37,10 +37,11 @@ <% end %> <% if presenter.calculation.present? %> - <%= render partial: "ticket_calculations_table", locals: { presenter: presenter } %>
+ <%= render partial: "ticket_calculations_table", locals: { presenter: presenter } %> <% end %> <% if presenter.relevant_historical_facts.any? %> +
<%= render partial: "historical_facts_table", locals: { presenter: presenter } %> <% end %> <% elsif current_user.nil? %> From 07ea7c3d11b4e7665ead9ffb92da2919a42fe3c7 Mon Sep 17 00:00:00 2001 From: moveson Date: Mon, 16 Dec 2024 11:43:58 -0700 Subject: [PATCH 02/10] Create the presenter in base view instead of partial --- .../lottery_entrants/_lottery_entrant_with_tickets.html.erb | 6 ++---- app/views/lottery_entrants/show.html.erb | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/app/views/lottery_entrants/_lottery_entrant_with_tickets.html.erb b/app/views/lottery_entrants/_lottery_entrant_with_tickets.html.erb index e494121db..de2ecff95 100644 --- a/app/views/lottery_entrants/_lottery_entrant_with_tickets.html.erb +++ b/app/views/lottery_entrants/_lottery_entrant_with_tickets.html.erb @@ -1,13 +1,11 @@ -<%# locals: (record:, calculation:) %> - -<% presenter = LotteryEntrantPresenter.new(record) %> +<%# locals: (presenter:) %> <%= turbo_frame_tag dom_id(presenter) do %>
- <%= render partial: "lottery_entrants/name_and_geolocation_with_icon", locals: { record: record } %> + <%= render partial: "lottery_entrants/name_and_geolocation_with_icon", locals: { record: presenter.__getobj__ } %>

<%= presenter.division_name %>

diff --git a/app/views/lottery_entrants/show.html.erb b/app/views/lottery_entrants/show.html.erb index ea1f62cf9..a203ff8be 100644 --- a/app/views/lottery_entrants/show.html.erb +++ b/app/views/lottery_entrants/show.html.erb @@ -1 +1 @@ -<%= render "lottery_entrant_with_tickets", record: @lottery_entrant %> +<%= render "lottery_entrant_with_tickets", presenter: LotteryEntrantPresenter.new(@lottery_entrant) %> From 33a2532e73bb6083193408354e306697ae1761e2 Mon Sep 17 00:00:00 2001 From: moveson Date: Mon, 16 Dec 2024 20:14:50 -0700 Subject: [PATCH 03/10] Rework My Stuff page with lazy loading and separate controller --- app/controllers/my_stuff_controller.rb | 45 +++++++ app/controllers/users_controller.rb | 15 ++- .../controllers/masonry_controller.js | 9 ++ app/policies/user_policy.rb | 10 +- app/presenters/my_stuff_presenter.rb | 2 +- app/views/layouts/_navigation_links.html.erb | 2 +- app/views/my_stuff/_event_series.html.erb | 9 ++ app/views/my_stuff/_events.html.erb | 9 ++ app/views/my_stuff/_interests.html.erb | 9 ++ app/views/my_stuff/_live_updates.html.erb | 9 ++ app/views/my_stuff/_organizations.html.erb | 16 +++ app/views/my_stuff/_results.html.erb | 9 ++ app/views/my_stuff/index.html.erb | 96 +++++++++++++ app/views/shared/_loading.html.erb | 1 + app/views/users/my_stuff.html.erb | 127 ------------------ config/routes.rb | 16 ++- 16 files changed, 234 insertions(+), 150 deletions(-) create mode 100644 app/controllers/my_stuff_controller.rb create mode 100644 app/views/my_stuff/_event_series.html.erb create mode 100644 app/views/my_stuff/_events.html.erb create mode 100644 app/views/my_stuff/_interests.html.erb create mode 100644 app/views/my_stuff/_live_updates.html.erb create mode 100644 app/views/my_stuff/_organizations.html.erb create mode 100644 app/views/my_stuff/_results.html.erb create mode 100644 app/views/my_stuff/index.html.erb create mode 100644 app/views/shared/_loading.html.erb delete mode 100644 app/views/users/my_stuff.html.erb diff --git a/app/controllers/my_stuff_controller.rb b/app/controllers/my_stuff_controller.rb new file mode 100644 index 000000000..73c333520 --- /dev/null +++ b/app/controllers/my_stuff_controller.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +class MyStuffController < ApplicationController + before_action :authenticate_user! + before_action :set_presenter + before_action :test_sleep, except: :index + + def index + end + + def events + render partial: "events", locals: { presenter: @presenter } + end + + def event_series + render partial: "event_series", locals: { presenter: @presenter } + end + + def interests + render partial: "interests", locals: { presenter: @presenter } + end + + def live_updates + render partial: "live_updates", locals: { presenter: @presenter } + end + + def organizations + render partial: "organizations", locals: { presenter: @presenter } + end + + def results + render partial: "results", locals: { presenter: @presenter } + end + + private + + def test_sleep + sleep rand(3) + end + + def set_presenter + @presenter = MyStuffPresenter.new(current_user) + end + +end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 5f2570314..6dc980b17 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,10 +1,14 @@ +# frozen_string_literal: true + class UsersController < ApplicationController before_action :authenticate_user! - before_action :set_user, except: :index + before_action :set_user, only: [:update, :destroy] + before_action :authorize_user, only: [:update, :destroy] after_action :verify_authorized def index authorize User + users = User.with_avatar_names.includes(:avatar) .where(prepared_params[:filter]) .search(prepared_params[:search]) @@ -22,7 +26,6 @@ def index end def update - authorize @user if @user.update(secure_params) redirect_to users_path, notice: "User updated." else @@ -31,18 +34,16 @@ def update end def destroy - authorize @user @user.destroy redirect_to users_path, notice: "User deleted." end - def my_stuff + private + + def authorize_user authorize @user - @presenter = MyStuffPresenter.new(@user) end - private - def secure_params params.require(:user).permit(:role) end diff --git a/app/javascript/controllers/masonry_controller.js b/app/javascript/controllers/masonry_controller.js index 00afdf489..a61b8e474 100644 --- a/app/javascript/controllers/masonry_controller.js +++ b/app/javascript/controllers/masonry_controller.js @@ -4,6 +4,15 @@ import Masonry from "masonry-layout" export default class extends Controller { connect() { this.masonry = new Masonry(this.element) + + // Frames resize when they load, so Masonry needs to recalculate the layout + const frames = this.element.getElementsByTagName("turbo-frame") + + Array.from(frames).forEach((frame) => { + frame.addEventListener("turbo:frame-load", () => { + this.masonry.layout(); + }); + }); } disconnect() { diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb index 20958abc1..0b0cb0517 100644 --- a/app/policies/user_policy.rb +++ b/app/policies/user_policy.rb @@ -33,18 +33,10 @@ def index? end def update? - current_user.admin? + index? end def destroy? current_user.admin? && (current_user != user_record) end - - def current? - current_user.present? - end - - def my_stuff? - current_user.admin? || (current_user == user_record) - end end diff --git a/app/presenters/my_stuff_presenter.rb b/app/presenters/my_stuff_presenter.rb index a7b82ee31..2a10d48f5 100644 --- a/app/presenters/my_stuff_presenter.rb +++ b/app/presenters/my_stuff_presenter.rb @@ -42,7 +42,7 @@ def recent_user_efforts(number) end def user_efforts - return nil unless avatar + return [] unless avatar @user_efforts ||= avatar.efforts.includes(:split_times).sort_by(&:calculated_start_time).reverse end diff --git a/app/views/layouts/_navigation_links.html.erb b/app/views/layouts/_navigation_links.html.erb index adbb14b44..1d7b79630 100644 --- a/app/views/layouts/_navigation_links.html.erb +++ b/app/views/layouts/_navigation_links.html.erb @@ -2,7 +2,7 @@ <%= link_to "Events", event_groups_path, class: "nav-link" %> <%= link_to "Organizations", organizations_path, class: "nav-link" %> <% if current_user %> - <%= link_to "My Stuff", my_stuff_user_path(current_user), class: "nav-link" %> + <%= link_to "My Stuff", my_stuff_path, class: "nav-link" %> <%= link_to "Imports", import_jobs_path, class: "nav-link" %> <%= link_to "Exports", export_jobs_path, class: "nav-link" %> <% end %> diff --git a/app/views/my_stuff/_event_series.html.erb b/app/views/my_stuff/_event_series.html.erb new file mode 100644 index 000000000..e43d6696a --- /dev/null +++ b/app/views/my_stuff/_event_series.html.erb @@ -0,0 +1,9 @@ +<%# locals: (presenter:) %> + + + <% presenter.recent_event_series(10).each do |series| %> +

+ <%= link_to series.name, organization_event_series_path(series.organization, series) %> +

+ <% end %> +
diff --git a/app/views/my_stuff/_events.html.erb b/app/views/my_stuff/_events.html.erb new file mode 100644 index 000000000..46856a4b6 --- /dev/null +++ b/app/views/my_stuff/_events.html.erb @@ -0,0 +1,9 @@ +<%# locals: (presenter:) %> + + + <% presenter.recent_event_groups(20).each do |event_group| %> +

+ <%= link_to event_group.name, event_group_path(event_group) %> +

+ <% end %> +
diff --git a/app/views/my_stuff/_interests.html.erb b/app/views/my_stuff/_interests.html.erb new file mode 100644 index 000000000..a058b81c5 --- /dev/null +++ b/app/views/my_stuff/_interests.html.erb @@ -0,0 +1,9 @@ +<%# locals: (presenter:) %> + + + <% presenter.interests.each do |person| %> +

+ <%= link_to person.full_name, person_path(person) %> +

+ <% end %> +
diff --git a/app/views/my_stuff/_live_updates.html.erb b/app/views/my_stuff/_live_updates.html.erb new file mode 100644 index 000000000..9379b556d --- /dev/null +++ b/app/views/my_stuff/_live_updates.html.erb @@ -0,0 +1,9 @@ +<%# locals: (presenter:) %> + + + <% presenter.watch_efforts.each do |effort| %> +

+ <%= link_to "#{effort.full_name} at #{effort.event_name}", effort_path(effort) %> +

+ <% end %> +
diff --git a/app/views/my_stuff/_organizations.html.erb b/app/views/my_stuff/_organizations.html.erb new file mode 100644 index 000000000..bc7b2f8f7 --- /dev/null +++ b/app/views/my_stuff/_organizations.html.erb @@ -0,0 +1,16 @@ +<%# locals: (presenter:) %> + + + <% presenter.owned_organizations.each do |organization| %> +

+ <%= link_to organization.name, organization_path(organization) %> + Owner +

+ <% end %> + <% presenter.steward_organizations.each do |organization| %> +

+ <%= link_to organization.name, organization_path(organization) %> + Steward +

+ <% end %> +
diff --git a/app/views/my_stuff/_results.html.erb b/app/views/my_stuff/_results.html.erb new file mode 100644 index 000000000..b69551b36 --- /dev/null +++ b/app/views/my_stuff/_results.html.erb @@ -0,0 +1,9 @@ +<%# locals: (presenter:) %> + + + <% presenter.recent_user_efforts(20).each do |effort| %> +

+ <%= link_to effort.event_name, effort_path(effort) %> +

+ <% end %> +
diff --git a/app/views/my_stuff/index.html.erb b/app/views/my_stuff/index.html.erb new file mode 100644 index 000000000..27d966cce --- /dev/null +++ b/app/views/my_stuff/index.html.erb @@ -0,0 +1,96 @@ +<% content_for :title do %> + <% "OpenSplitTime: My stuff - #{@presenter.full_name}" %> +<% end %> + +<% content_for(:container_type) do %>skip +<% end %> + +
+
+
+
+
+

<%= @presenter.full_name %>

+ +
+
+
+
+
+ +
+
+
+
+

My Results

+
+ + <%= render partial: "shared/loading" %> + +
+
+
+ +
+
+

My Events

+
+ + <%= render partial: "shared/loading" %> + +
+
+
+ +
+
+

My Event Series

+
+ + <%= render partial: "shared/loading" %> + +
+
+
+ +
+
+

My Interests

+
+ + <%= render partial: "shared/loading" %> + +
+
+
+ +
+
+

My Live Updates

+
+ + <%= render partial: "shared/loading" %> + +
+
+
+ +
+
+

My Organizations

+
+ + <%= render partial: "shared/loading" %> + +
+
+
+
+
diff --git a/app/views/shared/_loading.html.erb b/app/views/shared/_loading.html.erb new file mode 100644 index 000000000..18d3aa058 --- /dev/null +++ b/app/views/shared/_loading.html.erb @@ -0,0 +1 @@ +<%= fa_icon("spinner", text: "Loading", class: "fa-spin") %> diff --git a/app/views/users/my_stuff.html.erb b/app/views/users/my_stuff.html.erb deleted file mode 100644 index 048da80fe..000000000 --- a/app/views/users/my_stuff.html.erb +++ /dev/null @@ -1,127 +0,0 @@ -<% content_for :title do %> - <% "OpenSplitTime: My stuff - #{@presenter.full_name}" %> -<% end %> - -<% content_for(:container_type) do %>skip -<% end %> - -
-
-
-
-
-

<%= @presenter.full_name %>

- -
-
-
-
-
- -
-
- <% if @presenter.user_efforts.present? %> -
-
-

My Results

-
- <% @presenter.recent_user_efforts(10).each do |effort| %> -

- <%= link_to effort.event_name, effort_path(effort) %> -

- <% end %> -
-
-
- <% end %> - - <% if @presenter.event_groups.present? %> -
-
-

My Events

-
- <% @presenter.recent_event_groups(10).each do |event_group| %> -

- <%= link_to event_group.name, event_group_path(event_group) %> -

- <% end %> -
-
-
- <% end %> - - <% if @presenter.event_series.present? %> -
-
-

My Event Series

-
- <% @presenter.recent_event_series(10).each do |series| %> -

- <%= link_to series.name, organization_event_series_path(series.organization, series) %> -

- <% end %> -
-
-
- <% end %> - - <% if @presenter.interests.present? %> -
-
-

My Interests

-
- <% @presenter.interests.each do |person| %> -

- <%= link_to person.full_name, person_path(person) %> -

- <% end %> -
-
-
- <% end %> - - <% if @presenter.watch_efforts.present? %> -
-
-

My Live Updates

-
- <% @presenter.watch_efforts.each do |effort| %> -

- <%= link_to "#{effort.full_name} at #{effort.event_name}", effort_path(effort) %> -

- <% end %> -
-
-
- <% end %> - - <% if @presenter.organizations.present? %> -
-
-

My Organizations

-
- <% @presenter.owned_organizations.each do |organization| %> -

- <%= link_to organization.name, organization_path(organization) %> - Owner -

- <% end %> - <% @presenter.steward_organizations.each do |organization| %> -

- <%= link_to organization.name, organization_path(organization) %> - Steward -

- <% end %> -
-
-
- <% end %> -
-
diff --git a/config/routes.rb b/config/routes.rb index b42edeb2d..a73bbec8d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -40,6 +40,16 @@ get "api", to: "visitors#api" end + scope :my_stuff, controller: :my_stuff, as: :my_stuff do + get '/', action: :index + get :events + get :event_series + get :interests + get :live_updates + get :organizations + get :results + end + namespace :webhooks do resources :sendgrid_events, only: [:create] end @@ -64,11 +74,7 @@ get "/users/auth/failure" => "users/omniauth_callbacks#failure" end - resources :users, only: [:index, :update, :destroy] do - member do - get :my_stuff - end - end + resources :users, only: [:index, :update, :destroy] resources :credentials, only: [:create, :update, :destroy] From dcfa053bc7b64f9d64cd3711f04440a7a20b6451 Mon Sep 17 00:00:00 2001 From: moveson Date: Mon, 16 Dec 2024 20:15:48 -0700 Subject: [PATCH 04/10] Remove test sleep from my stuff controller --- app/controllers/my_stuff_controller.rb | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/controllers/my_stuff_controller.rb b/app/controllers/my_stuff_controller.rb index 73c333520..d94072829 100644 --- a/app/controllers/my_stuff_controller.rb +++ b/app/controllers/my_stuff_controller.rb @@ -3,7 +3,6 @@ class MyStuffController < ApplicationController before_action :authenticate_user! before_action :set_presenter - before_action :test_sleep, except: :index def index end @@ -34,12 +33,7 @@ def results private - def test_sleep - sleep rand(3) - end - def set_presenter @presenter = MyStuffPresenter.new(current_user) end - end From a655dff28471839d0183ec9551b0273174645f77 Mon Sep 17 00:00:00 2001 From: moveson Date: Mon, 16 Dec 2024 20:43:00 -0700 Subject: [PATCH 05/10] Improve efficiency of results query --- app/presenters/my_stuff_presenter.rb | 4 ++-- app/presenters/visitor_index_presenter.rb | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/app/presenters/my_stuff_presenter.rb b/app/presenters/my_stuff_presenter.rb index 2a10d48f5..c07fcc133 100644 --- a/app/presenters/my_stuff_presenter.rb +++ b/app/presenters/my_stuff_presenter.rb @@ -42,9 +42,9 @@ def recent_user_efforts(number) end def user_efforts - return [] unless avatar + return Effort.none unless avatar - @user_efforts ||= avatar.efforts.includes(:split_times).sort_by(&:calculated_start_time).reverse + @user_efforts ||= avatar.efforts.joins(:event).includes(event: :event_group).order("events.scheduled_start_time desc") end def interests diff --git a/app/presenters/visitor_index_presenter.rb b/app/presenters/visitor_index_presenter.rb index ccd13009c..39a7654bf 100644 --- a/app/presenters/visitor_index_presenter.rb +++ b/app/presenters/visitor_index_presenter.rb @@ -13,10 +13,6 @@ def upcoming_courses(number) Course.where("next_start_time > ?", Time.current).order(:next_start_time).limit(number) end - def recent_user_efforts - @recent_user_efforts ||= avatar ? avatar.efforts.joins(:event).includes(event: :event_group).order("events.scheduled_start_time desc") : [] - end - private attr_reader :current_user From 3546959b0f726508f426bb303d543fce83fe581f Mon Sep 17 00:00:00 2001 From: moveson Date: Mon, 16 Dec 2024 20:43:21 -0700 Subject: [PATCH 06/10] Set target="_top" in turbo frames so links will work --- app/views/my_stuff/index.html.erb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/views/my_stuff/index.html.erb b/app/views/my_stuff/index.html.erb index 27d966cce..e15521e79 100644 --- a/app/views/my_stuff/index.html.erb +++ b/app/views/my_stuff/index.html.erb @@ -31,7 +31,7 @@

My Results

- + <%= render partial: "shared/loading" %>
@@ -42,7 +42,7 @@

My Events

- + <%= render partial: "shared/loading" %>
@@ -53,7 +53,7 @@

My Event Series

- + <%= render partial: "shared/loading" %>
@@ -64,7 +64,7 @@

My Interests

- + <%= render partial: "shared/loading" %>
@@ -75,7 +75,7 @@

My Live Updates

- + <%= render partial: "shared/loading" %>
@@ -86,7 +86,7 @@

My Organizations

- + <%= render partial: "shared/loading" %>
From e7f46c5b0ef35e6ba3251ba381d2869d8ce8df83 Mon Sep 17 00:00:00 2001 From: moveson Date: Mon, 16 Dec 2024 21:07:01 -0700 Subject: [PATCH 07/10] Add service requirements card --- app/controllers/my_stuff_controller.rb | 4 ++ app/models/lottery_entrant.rb | 1 + app/presenters/my_stuff_presenter.rb | 5 ++ .../my_stuff/_service_requirements.html.erb | 9 ++++ app/views/my_stuff/index.html.erb | 12 +++++ config/routes.rb | 1 + spec/models/lottery_entrant_spec.rb | 54 ++++++++++++++++++- 7 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 app/views/my_stuff/_service_requirements.html.erb diff --git a/app/controllers/my_stuff_controller.rb b/app/controllers/my_stuff_controller.rb index d94072829..4ca742b25 100644 --- a/app/controllers/my_stuff_controller.rb +++ b/app/controllers/my_stuff_controller.rb @@ -31,6 +31,10 @@ def results render partial: "results", locals: { presenter: @presenter } end + def service_requirements + render partial: "service_requirements", locals: { presenter: @presenter } + end + private def set_presenter diff --git a/app/models/lottery_entrant.rb b/app/models/lottery_entrant.rb index a8c26cbec..a4cc540fe 100644 --- a/app/models/lottery_entrant.rb +++ b/app/models/lottery_entrant.rb @@ -17,6 +17,7 @@ class LotteryEntrant < ApplicationRecord strip_attributes collapse_spaces: true capitalize_attributes :first_name, :last_name, :city + scope :belonging_to_user, ->(user) { where(email: user.email).or(where.not(person: nil).where(person: user.avatar)) } scope :accepted, -> { joins(:division_ranking).where(lotteries_division_rankings: { draw_status: :accepted }) } scope :waitlisted, -> { joins(:division_ranking).where(lotteries_division_rankings: { draw_status: :waitlisted }) } scope :drawn_beyond_waitlist, -> { joins(:division_ranking).where(lotteries_division_rankings: { draw_status: :drawn_beyond_waitlist }) } diff --git a/app/presenters/my_stuff_presenter.rb b/app/presenters/my_stuff_presenter.rb index c07fcc133..05b0b1cc0 100644 --- a/app/presenters/my_stuff_presenter.rb +++ b/app/presenters/my_stuff_presenter.rb @@ -25,6 +25,11 @@ def event_series EventSeries.includes(:events).where(organization: organizations) end + def lottery_entrants + LotteryEntrant.belonging_to_user(current_user) + .includes(:service_detail, division: { lottery: :organization }) + end + def organizations owned_organizations | steward_organizations end diff --git a/app/views/my_stuff/_service_requirements.html.erb b/app/views/my_stuff/_service_requirements.html.erb new file mode 100644 index 000000000..5340c8ca1 --- /dev/null +++ b/app/views/my_stuff/_service_requirements.html.erb @@ -0,0 +1,9 @@ +<%# locals: (presenter:) %> + + + <% presenter.lottery_entrants.each do |lottery_entrant| %> +

+ <%= link_to lottery_entrant.lottery.name, organization_lottery_entrant_service_detail_path(lottery_entrant.organization, lottery_entrant.lottery, lottery_entrant) %> +

+ <% end %> +
diff --git a/app/views/my_stuff/index.html.erb b/app/views/my_stuff/index.html.erb index e15521e79..f448a7ba9 100644 --- a/app/views/my_stuff/index.html.erb +++ b/app/views/my_stuff/index.html.erb @@ -27,6 +27,18 @@ data-controller="masonry" data-masonry='{"percentPosition": true }' style="position: relative"> + +
+
+

My Service Requirements

+
+ + <%= render partial: "shared/loading" %> + +
+
+
+

My Results

diff --git a/config/routes.rb b/config/routes.rb index a73bbec8d..a0ea7dc83 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -48,6 +48,7 @@ get :live_updates get :organizations get :results + get :service_requirements end namespace :webhooks do diff --git a/spec/models/lottery_entrant_spec.rb b/spec/models/lottery_entrant_spec.rb index 4060dc286..99550082e 100644 --- a/spec/models/lottery_entrant_spec.rb +++ b/spec/models/lottery_entrant_spec.rb @@ -12,10 +12,62 @@ it { is_expected.to strip_attribute(:state_code).collapse_spaces } it { is_expected.to strip_attribute(:country_code).collapse_spaces } - describe "scopes related to draw status" do + describe "scopes" do let(:existing_scope) { division.entrants } let(:division) { LotteryDivision.find_by(name: division_name) } + describe ".belonging_to_user" do + let(:result) { existing_scope.belonging_to_user(user) } + let(:user) { users(:fifth_user) } + let(:division) { lottery_divisions(:lottery_division_0001) } + let(:entrant_1) { lottery_entrants(:lottery_entrant_0001) } + let(:entrant_2) { lottery_entrants(:lottery_entrant_0002) } + let(:person) { people(:bruno_fadel) } + + context "when the user's avatar is the lottery entrant's person" do + before do + user.update(avatar: person) + entrant_1.update(person: person) + end + + it "returns a collection including that lottery entrant" do + expect(result.count).to eq(1) + expect(result).to include(entrant_1) + end + end + + context "when the user's email is the same as the lottery entrant's email" do + before do + entrant_1.update(email: user.email) + end + + it "returns a collection including that lottery entrant" do + expect(result.count).to eq(1) + expect(result).to include(entrant_1) + end + end + + context "when email matches one entrant and person matches another" do + before do + user.update(avatar: person) + entrant_1.update(person: person) + entrant_2.update(email: user.email) + end + + it "returns a collection including both entrants" do + expect(result.count).to eq(2) + expect(result).to include(entrant_1) + expect(result).to include(entrant_2) + end + end + + context "when no matches are found" do + it "returns an empty collection" do + expect(result).to be_empty + end + end + end + describe ".accepted" do let(:result) { existing_scope.accepted } From 7f0ab1d3587dcdf7aae984b5f8ff6794418078b1 Mon Sep 17 00:00:00 2001 From: moveson Date: Mon, 16 Dec 2024 21:15:10 -0700 Subject: [PATCH 08/10] Restore current? method to UserPolicy --- app/policies/user_policy.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb index 0b0cb0517..a83351152 100644 --- a/app/policies/user_policy.rb +++ b/app/policies/user_policy.rb @@ -39,4 +39,8 @@ def update? def destroy? current_user.admin? && (current_user != user_record) end + + def current? + current_user.present? + end end From 69358e1a14d7b5589d70756ff06f6823a81ec48a Mon Sep 17 00:00:00 2001 From: moveson Date: Mon, 16 Dec 2024 21:30:10 -0700 Subject: [PATCH 09/10] Fix system spec for My Stuff view --- spec/system/visit_my_stuff_page_spec.rb | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/spec/system/visit_my_stuff_page_spec.rb b/spec/system/visit_my_stuff_page_spec.rb index d406bd0ae..8e88b1bf6 100644 --- a/spec/system/visit_my_stuff_page_spec.rb +++ b/spec/system/visit_my_stuff_page_spec.rb @@ -2,7 +2,7 @@ require "rails_helper" -RSpec.describe "Visit the My Stuff page" do +RSpec.describe "Visit the My Stuff page", js: true do let(:steward) { users(:third_user) } let(:admin) { users(:admin_user) } let(:organization_1) { organizations(:hardrock) } @@ -15,31 +15,20 @@ scenario "The user is a non-admin user that is a steward of an organization" do login_as steward, scope: :user - visit my_stuff_user_path(steward) + visit_my_stuff_path verify_org_links_present(organization_1) end - scenario "The user is a non-admin user that attempts to reach the my_stuff page of another user" do - login_as steward, scope: :user - visit my_stuff_user_path(admin) - - expect(page).not_to have_content("My Events") - expect(page).not_to have_content("My Organizations") - end - - scenario "The user is an admin user signing into his own page" do + scenario "The user is an admin user" do login_as admin, scope: :user - visit my_stuff_user_path(admin) + visit_my_stuff_path verify_org_links_present(organization_2) end - scenario "The user is an admin user signing into another user page" do - login_as admin, scope: :user - visit my_stuff_user_path(steward) - - verify_org_links_present(organization_1) + def visit_my_stuff_path + visit my_stuff_path end def verify_org_links_present(organization) From 4667eed427aa2761f412ba75e3a56b6e528ffc75 Mon Sep 17 00:00:00 2001 From: moveson Date: Mon, 16 Dec 2024 21:47:06 -0700 Subject: [PATCH 10/10] Simplify system spec for the My Stuff page --- spec/system/visit_my_stuff_page_spec.rb | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/spec/system/visit_my_stuff_page_spec.rb b/spec/system/visit_my_stuff_page_spec.rb index 8e88b1bf6..e0486034d 100644 --- a/spec/system/visit_my_stuff_page_spec.rb +++ b/spec/system/visit_my_stuff_page_spec.rb @@ -2,39 +2,32 @@ require "rails_helper" -RSpec.describe "Visit the My Stuff page", js: true do - let(:steward) { users(:third_user) } +RSpec.describe "Visit the My Stuff page" do + let(:non_admin) { users(:third_user) } let(:admin) { users(:admin_user) } let(:organization_1) { organizations(:hardrock) } let(:organization_2) { organizations(:rattlesnake_ramble) } - before do - organization_1.stewards << steward - organization_2.stewards << admin - end - - scenario "The user is a non-admin user that is a steward of an organization" do - login_as steward, scope: :user + scenario "The user is a non-admin user" do + login_as non_admin, scope: :user visit_my_stuff_path - verify_org_links_present(organization_1) + verify_headings_present end scenario "The user is an admin user" do login_as admin, scope: :user visit_my_stuff_path - verify_org_links_present(organization_2) + verify_headings_present end def visit_my_stuff_path visit my_stuff_path end - def verify_org_links_present(organization) + def verify_headings_present expect(page).to have_content("My Events") expect(page).to have_content("My Organizations") - verify_link_present(organization) - organization.event_groups.each(&method(:verify_link_present)) end end