From 81ae6f75ed6b4cf3aee4f98cdadf81ee554f8183 Mon Sep 17 00:00:00 2001 From: bernardhanna Date: Wed, 16 Sep 2026 17:10:04 +0100 Subject: [PATCH] Show only upcoming activities on the online activities page The list filtered on the end date, so activities starting in 2020, 2021 and 2022 that carry an end date years in the future stayed on the page. Filter on the start date instead: 17 of the 225 listed activities had already started, including four dated before 2025. Grouping activities under the current month is no longer needed now that nothing earlier than today can appear. Co-authored-by: Cursor --- app/Livewire/OnlineCalendar.php | 34 ++--------- tests/Feature/OnlineEventsWorkflowTest.php | 67 ++++++++++++++-------- 2 files changed, 49 insertions(+), 52 deletions(-) diff --git a/app/Livewire/OnlineCalendar.php b/app/Livewire/OnlineCalendar.php index 1e9a7c03d..d4bc9f407 100644 --- a/app/Livewire/OnlineCalendar.php +++ b/app/Livewire/OnlineCalendar.php @@ -33,7 +33,7 @@ public function mount() ->orderBy('start_date') ->get(['start_date']) ->groupBy(function ($event) { - return $this->effectiveStart($event->start_date)->format('n/Y'); + return Carbon::parse($event->start_date)->format('n/Y'); }) ->map(function ($group, $id) { [$month, $year] = explode('/', $id); @@ -68,20 +68,10 @@ public function render() $monthStart = Carbon::createFromDate($this->selectedYear, $this->selectedMonth, 1)->startOfMonth(); - $query->where(function ($monthQuery) use ($monthStart) { - $monthQuery->whereBetween('start_date', [$monthStart, $monthStart->copy()->endOfMonth()]); - - if ($monthStart->isSameMonth(Carbon::now())) { - $monthQuery->orWhere('start_date', '<', $monthStart); - } - }); + $query->whereBetween('start_date', [$monthStart, $monthStart->copy()->endOfMonth()]); } - $events = $query->get() - ->sortBy(function ($event) { - return $this->effectiveStart($event->start_date)->getTimestamp(); - }) - ->values(); + $events = $query->get(); $events->each(function ($event) { $event->title = str_limit($event->title, 50); @@ -133,24 +123,12 @@ public function render() private function baseQuery() { - // Only the end date gates the list: an activity that began earlier but has not - // finished is still open to participants. + // The start date alone decides what is upcoming. Gating on the end date instead + // surfaced activities starting in 2020-2022 that carry an end date years away. return Event::where([ 'activity_type' => 'open-online', 'status' => 'APPROVED', - ])->where('end_date', '>=', Carbon::now()); - } - - /** - * Activities already under way are listed under the current month rather than the - * month they originally started in, which may be long past. - */ - private function effectiveStart($startDate): Carbon - { - $start = Carbon::parse($startDate); - $currentMonth = Carbon::now()->firstOfMonth(); - - return $start->lessThan($currentMonth) ? $currentMonth : $start; + ])->where('start_date', '>=', Carbon::today()); } private function eventMatchesLanguage($event, string $selectedLanguage): bool diff --git a/tests/Feature/OnlineEventsWorkflowTest.php b/tests/Feature/OnlineEventsWorkflowTest.php index 66084cc70..37f772623 100644 --- a/tests/Feature/OnlineEventsWorkflowTest.php +++ b/tests/Feature/OnlineEventsWorkflowTest.php @@ -321,67 +321,86 @@ public function online_activities_month_filter_only_shows_events_for_selected_mo } #[Test] - public function online_activities_page_lists_activities_already_under_way(): void + public function online_activities_page_excludes_activities_that_already_started(): void { $this->seed('RolesAndPermissionsSeeder'); - $ongoing = \App\Event::factory()->create([ - 'start_date' => Carbon::now()->subMonths(4), - 'end_date' => Carbon::now()->addMonths(6), + // Reported by the community: activities dated 2020-2022 were on the page because + // they carry an end date years in the future. + $staleStartDate = \App\Event::factory()->create([ + 'start_date' => Carbon::now()->subYears(5), + 'end_date' => Carbon::now()->addYear(), 'status' => 'APPROVED', 'activity_type' => 'open-online', 'highlighted_status' => 'NONE', 'language' => ['en'], - 'title' => 'Still Running Open Online Activity', + 'title' => 'Started Years Ago Ends Far Away', ]); - $finished = \App\Event::factory()->create([ - 'start_date' => Carbon::now()->subMonths(4), - 'end_date' => Carbon::now()->subMonth(), + $startedThisMonth = \App\Event::factory()->create([ + 'start_date' => Carbon::now()->startOfMonth(), + 'end_date' => Carbon::now()->addMonths(2), 'status' => 'APPROVED', 'activity_type' => 'open-online', 'highlighted_status' => 'NONE', 'language' => ['en'], - 'title' => 'Already Finished Open Online Activity', + 'title' => 'Started Earlier This Month', + ]); + + $upcoming = \App\Event::factory()->create([ + 'start_date' => Carbon::now()->addWeek(), + 'end_date' => Carbon::now()->addWeek()->addDay(), + 'status' => 'APPROVED', + 'activity_type' => 'open-online', + 'highlighted_status' => 'NONE', + 'language' => ['en'], + 'title' => 'Genuinely Upcoming Activity', ]); $this->get('/online-activities') ->assertStatus(200) - ->assertSee($ongoing->title) - ->assertDontSee($finished->title); + ->assertSee($upcoming->title) + ->assertDontSee($staleStartDate->title) + ->assertDontSee($startedThisMonth->title); } #[Test] - public function activities_already_under_way_are_listed_under_the_current_month(): void + public function the_month_filter_only_offers_months_that_are_still_to_come(): void { $this->seed('RolesAndPermissionsSeeder'); - $startedFourMonthsAgo = Carbon::now()->subMonths(4); + $pastStart = Carbon::now()->subYears(5); - $ongoing = \App\Event::factory()->create([ - 'start_date' => $startedFourMonthsAgo, - 'end_date' => Carbon::now()->addMonths(6), + \App\Event::factory()->create([ + 'start_date' => $pastStart, + 'end_date' => Carbon::now()->addYear(), 'status' => 'APPROVED', 'activity_type' => 'open-online', 'highlighted_status' => 'NONE', 'language' => ['en'], - 'title' => 'Ongoing Grouped Under Current Month', + 'title' => 'Stale Start Date Activity', ]); - $now = Carbon::now(); + $nextMonth = Carbon::now()->addMonthNoOverflow()->startOfMonth(); - \Livewire\Livewire::test(\App\Livewire\OnlineCalendar::class) - ->set('selectedDate', $now->month.'/'.$now->year) - ->assertSee($ongoing->title); + \App\Event::factory()->create([ + 'start_date' => $nextMonth->copy()->addDays(3), + 'end_date' => $nextMonth->copy()->addDays(4), + 'status' => 'APPROVED', + 'activity_type' => 'open-online', + 'highlighted_status' => 'NONE', + 'language' => ['en'], + 'title' => 'Next Month Activity', + ]); $monthIds = collect(\Livewire\Livewire::test(\App\Livewire\OnlineCalendar::class)->get('months')) ->pluck('id'); - $this->assertContains($now->month.'/'.$now->year, $monthIds); + $this->assertContains($nextMonth->month.'/'.$nextMonth->year, $monthIds); $this->assertNotContains( - $startedFourMonthsAgo->month.'/'.$startedFourMonthsAgo->year, + $pastStart->month.'/'.$pastStart->year, $monthIds, - 'The month filter should not offer a past month just because an ongoing activity started then.' + 'A past month must not appear in the filter just because an activity carries a far-off end date.' ); }