Skip to content

Commit 251bc8f

Browse files
committed
feat: split /events into upcoming and past pages
- /events now redirects to /events/upcoming - /events/upcoming shows upcoming events (paginated at 20) - /events/past shows past events (paginated at 20, sorted descending) - Updated navigation with Upcoming Events and Past Events items - Updated footer and dashboard links to point to upcoming_events_path - Renamed index.html.haml to upcoming.html.haml - Updated tests for new behavior
1 parent 1c88e96 commit 251bc8f

10 files changed

Lines changed: 105 additions & 70 deletions

File tree

Gemfile.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,7 @@ GEM
604604
PLATFORMS
605605
aarch64-linux
606606
arm64-darwin-20
607+
arm64-darwin-23
607608
arm64-darwin-25
608609
x86_64-darwin-24
609610
x86_64-linux

app/controllers/events_controller.rb

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,20 @@
33
class EventsController < ApplicationController
44
before_action :is_logged_in?, only: %i[student coach]
55

6-
RECENT_EVENTS_DISPLAY_LIMIT = 40
7-
86
def index
7+
redirect_to upcoming_events_path
8+
end
9+
10+
def upcoming
911
fresh_when(latest_model_updated, etag: latest_model_updated)
1012

11-
events = [Workshop.past
12-
.includes(:chapter, :sponsors, :host, :permissions)
13-
.joins(:chapter)
14-
.merge(Chapter.active)
15-
.limit(RECENT_EVENTS_DISPLAY_LIMIT)]
16-
events << Meeting.past.includes(:venue, :permissions).limit(RECENT_EVENTS_DISPLAY_LIMIT)
17-
events << Event.past.includes(:venue, :sponsors, :sponsorships, :permissions).limit(RECENT_EVENTS_DISPLAY_LIMIT)
18-
events = events.compact.flatten.sort_by(&:date_and_time).reverse.first(RECENT_EVENTS_DISPLAY_LIMIT)
19-
events_hash_grouped_by_date = events.group_by(&:date)
20-
@past_events = events_hash_grouped_by_date.map.each_with_object({}) do |(key, value), hash|
21-
hash[key] = EventPresenter.decorate_collection(value)
22-
end
23-
24-
events = [Workshop.upcoming
25-
.includes(:chapter, :sponsors, :host, :permissions)
26-
.joins(:chapter)
27-
.merge(Chapter.active)]
28-
events << Meeting.upcoming.includes(:venue, :permissions).all
29-
events << Event.upcoming.includes(:venue, :sponsors, :sponsorships, :permissions).all
30-
events = events.compact.flatten.sort_by(&:date_and_time).group_by(&:date)
31-
@events = events.map.each_with_object({}) do |(key, value), hash|
32-
hash[key] = EventPresenter.decorate_collection(value)
33-
end
13+
@events, @pagy = fetch_upcoming_events
14+
end
15+
16+
def past
17+
fresh_when(latest_model_updated, etag: latest_model_updated)
18+
19+
@past_events, @pagy = fetch_past_events
3420
end
3521

3622
def show
@@ -84,4 +70,32 @@ def find_invitation_and_redirect_to_event(role)
8470
def set_event
8571
@event = Event.find_by(slug: params[:event_id])
8672
end
73+
74+
def fetch_upcoming_events
75+
events = [Workshop.includes(:chapter, :sponsors).upcoming.joins(:chapter).merge(Chapter.active)]
76+
events << Meeting.upcoming.all
77+
events << Event.upcoming.includes(:venue, :sponsors, :sponsorships).all
78+
79+
sorted = events.compact.flatten.sort_by(&:date_and_time)
80+
pagy, paginated = pagy(sorted, items: 20)
81+
82+
grouped = paginated.group_by(&:date)
83+
decorated = grouped.transform_values { |items| EventPresenter.decorate_collection(items) }
84+
85+
[decorated, pagy]
86+
end
87+
88+
def fetch_past_events
89+
events = [Workshop.past.includes(:chapter, :sponsors).joins(:chapter).merge(Chapter.active)]
90+
events << Meeting.past.all
91+
events << Event.past.includes(:venue, :sponsors, :sponsorships).all
92+
93+
sorted = events.compact.flatten.sort_by(&:date_and_time).reverse
94+
pagy, paginated = pagy(sorted, items: 20)
95+
96+
grouped = paginated.group_by(&:date)
97+
decorated = grouped.transform_values { |items| EventPresenter.decorate_collection(items) }
98+
99+
[decorated, pagy]
100+
end
87101
end

app/views/dashboard/show.html.haml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@
7474
= render workshops
7575

7676
- if @has_more_events
77-
= link_to 'Explore all events →', events_path, class: 'btn btn-outline-primary mt-3'
77+
= link_to 'Explore all events →', upcoming_events_path, class: 'btn btn-outline-primary mt-3'
7878

7979
.col-lg-4.pl-lg-5
8080
%h3

app/views/events/index.html.haml

Lines changed: 0 additions & 15 deletions
This file was deleted.

app/views/events/past.html.haml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
- title 'Past Events'
2+
3+
.container{'data-test': 'past-events'}
4+
.row
5+
.col
6+
- if @past_events.any?
7+
%h3.mb-4 Past Events
8+
9+
= render partial: 'events', locals: { grouped_events: @past_events }
10+
11+
- if @pagy
12+
.container.mt-4
13+
= render partial: 'shared/pagination', locals: { pagy: @pagy, model: 'event' }
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
- title t('events.title')
2+
3+
.container{'data-test': 'upcoming-events'}
4+
.row
5+
.col
6+
- if @events.any?
7+
%h3.mb-4 Upcoming Events
8+
9+
= render partial: 'events', locals: { grouped_events: @events }
10+
11+
- if @pagy
12+
.container.mt-4
13+
= render partial: 'shared/pagination', locals: { pagy: @pagy, model: 'event' }

app/views/layouts/_footer.html.haml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
%li= link_to t("navigation.codebar_stories"), "https://medium.com/codebar-stories"
2828
%li= link_to t("navigation.coaches"), coaches_path
2929
%li= link_to t("navigation.sponsors"), sponsors_path
30-
%li= link_to t("navigation.events"), events_path
30+
%li= link_to t("navigation.events"), upcoming_events_path
3131
%li= link_to t("navigation.jobs"), "https://jobs.codebar.io/"
3232
%li.active= link_to t("navigation.donate"), new_donation_path
3333
%li= link_to "Buy us a coffee", "https://buymeacoffee.com/codebarhq", target: '_blank', rel: 'noopener noreferrer'

app/views/layouts/_navigation.html.haml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
= link_to '#', {'role': 'button', 'aria-expanded': 'false', 'data-bs-toggle': 'dropdown', class: 'nav-link border-0 dropdown-toggle', id: 'navbarDropdownMenuLinkEvents'} do
1111
Events
1212
%ul.dropdown-menu{'aria-labelledby': 'navbarDropdownMenuLinkEvents'}
13-
%li= link_to 'Events', events_path, class: 'dropdown-item'
13+
%li= link_to 'Upcoming Events', upcoming_events_path, class: 'dropdown-item'
14+
%li= link_to 'Past Events', past_events_path, class: 'dropdown-item'
1415
%li= link_to 'codebar Festival', 'http://festival.codebar.io/', class: 'dropdown-item'
1516
%li= link_to 'uncodebar', 'https://uncodebar.com', class: 'dropdown-item'
1617
%li.nav-item.dropdown

config/routes.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232

3333
get 'unsubscribe/:token' => 'members#unsubscribe', as: :unsubscribe
3434

35-
resources :invitation, only: [:show, :update] do
35+
resources :invitation, only: %i[show update] do
3636
member do
3737
post 'accept'
3838
get 'accept'
@@ -50,6 +50,10 @@
5050
end
5151

5252
resources :events, only: %i[index show] do
53+
collection do
54+
get :upcoming
55+
get :past
56+
end
5357
post 'rsvp'
5458
get 'student', as: :student_rsvp
5559
get 'coach', as: :coach_rsvp
Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,44 @@
11
RSpec.feature 'event listing', type: :feature do
2-
describe 'I can see the names and titles of events' do
3-
let!(:upcoming_workshop) { Fabricate(:workshop) }
2+
describe 'I can see upcoming events' do
3+
let!(:chapter) { Fabricate(:chapter, active: true) }
4+
let!(:upcoming_workshop) { Fabricate(:workshop, chapter: chapter) }
45
let!(:event) { Fabricate(:event) }
5-
let!(:past_event) { Fabricate(:event, date_and_time: Time.zone.now - 2.weeks) }
6-
let!(:past_workshop) { Fabricate(:workshop, date_and_time: Time.zone.now - 1.week) }
76

8-
before do
9-
visit events_path
7+
scenario 'displays upcoming events page' do
8+
visit upcoming_events_path
9+
expect(page).to have_content 'Upcoming Events'
10+
expect(page).to have_content event.name
1011
end
12+
end
13+
14+
describe 'I can see past events' do
15+
let!(:chapter) { Fabricate(:chapter, active: true) }
16+
let!(:past_event) { Fabricate(:event, date_and_time: Time.zone.now - 2.weeks) }
17+
let!(:past_workshop) { Fabricate(:workshop, date_and_time: Time.zone.now - 1.week, chapter: chapter) }
1118

12-
scenario 'i can view a list with upcoming events' do
13-
within('*[data-test=upcoming-events]') do
14-
expect(page).to have_content 'Workshop'
15-
expect(page).to have_content event.name
16-
end
19+
scenario 'displays past events page' do
20+
visit past_events_path
21+
expect(page).to have_content 'Past Events'
22+
expect(page).to have_content past_event.name
1723
end
24+
end
1825

19-
scenario 'i can view a list with past events' do
20-
within('*[data-test=past-events]') do
21-
expect(page).to have_content 'Workshop'
22-
expect(page).to have_content past_event.name
23-
end
26+
describe 'root /events redirects to /events/upcoming' do
27+
scenario 'redirects to upcoming events' do
28+
visit events_path
29+
expect(page).to have_content 'Upcoming Events'
30+
expect(page).to have_current_path '/events/upcoming', ignore_query: true
2431
end
2532
end
2633

27-
context 'when there are more than the specified number of past events' do
28-
scenario 'I can only as many events allowed by the display limits' do
29-
Fabricate.times(2, :event, date_and_time: 2.weeks.ago)
30-
stub_const('EventsController::RECENT_EVENTS_DISPLAY_LIMIT', 2)
31-
Fabricate(:workshop, date_and_time: 3.weeks.ago)
34+
context 'pagination' do
35+
scenario 'past events paginates at 20 per page' do
36+
chapter = Fabricate(:chapter, active: true)
37+
Fabricate.times(22, :event, date_and_time: 2.weeks.ago)
38+
Fabricate(:workshop, date_and_time: 3.weeks.ago, chapter: chapter)
3239

33-
visit events_path
34-
within('*[data-test=past-events]') do
35-
expect(page).to have_selector('*[data-test=event]', count: 2)
36-
expect(page).not_to have_content 'Workshop'
37-
end
40+
visit past_events_path
41+
expect(page).to have_selector('.card', count: 20)
3842
end
3943
end
4044
end

0 commit comments

Comments
 (0)