Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions app/Livewire/PartnerFilterComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ class PartnerFilterComponent extends Component
// This function will be triggered when a filter is selected
public function selectFilter($filter)
{
$this->selectedFilter = $filter; // Update the filter
$this->dispatch('filterChanged', filter: $filter); // Dispatch an event in Livewire v3
$this->selectedFilter = $filter;
$this->dispatch('filterChanged', filter: $filter)
->to(PartnerContentComponent::class);
}

public function render()
Expand Down
8 changes: 6 additions & 2 deletions resources/views/livewire/filter-component.blade.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
<div>
<nav class="flex flex-wrap gap-2.5 justify-center items-start text-base text-black rounded-[32px] max-md:max-w-full">
@foreach($filters as $filter)
<a href="#" wire:click.prevent="selectFilter('{{ $filter }}')" class="gap-2.5 self-stretch text-[16px] leading-5 hover:bg-secondary hover:text-white px-6 py-2.5 {{ $selectedFilter === $filter ? 'bg-[#1C4DA1] text-white' : 'bg-[#CCF0F9] text-black' }} rounded-3xl max-md:px-5">
<button
type="button"
wire:click="selectFilter('{{ $filter }}')"
class="gap-2.5 self-stretch text-[16px] leading-5 hover:bg-secondary hover:text-white px-6 py-2.5 {{ $selectedFilter === $filter ? 'bg-[#1C4DA1] text-white' : 'bg-[#CCF0F9] text-black' }} rounded-3xl max-md:px-5"
>
{{ $filter }}
</a>
</button>
@endforeach
</nav>
</div>
5 changes: 4 additions & 1 deletion resources/views/static/sponsors.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
}
}
</style>
@section('content')
{{-- Must use non-vue-content: Vue mounts on #app and re-renders its DOM, which
detaches Livewire's bound elements and leaves unbound clones. Filter tabs
then look clickable but never fire wire:click / filterChanged. --}}
@section('non-vue-content')
<section id="codeweek-sponsors-page" class="font-['Blinker'] overflow-hidden">
<section class="flex overflow-hidden relative flex-col bg-violet-gradient">
<div class="relative w-full transition-all">
Expand Down
55 changes: 55 additions & 0 deletions tests/Feature/PartnersPageFilterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace Tests\Feature;

use App\Livewire\PartnerContentComponent;
use App\Livewire\PartnerFilterComponent;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Livewire\Livewire;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;

final class PartnersPageFilterTest extends TestCase
{
use DatabaseMigrations;

#[Test]
public function partners_page_renders_livewire_outside_the_vue_app_root(): void
{
$html = $this->get(route('sponsors'))->assertOk()->getContent();

$appPos = strpos($html, 'id="app"');
$nonVuePos = strpos($html, 'id="non-vue"');
$sponsorsPos = strpos($html, 'id="codeweek-sponsors-page"');

$this->assertNotFalse($appPos);
$this->assertNotFalse($nonVuePos);
$this->assertNotFalse($sponsorsPos);

// Vue mounts on #app and re-renders its DOM, which strips Livewire wire: bindings.
// Partner tabs must live in #non-vue so filter clicks keep working.
$this->assertGreaterThan(
$nonVuePos,
$sponsorsPos,
'Partners page must render in #non-vue, not #app'
);
}

#[Test]
public function selecting_a_filter_updates_partner_content(): void
{
Livewire::test(PartnerFilterComponent::class)
->call('selectFilter', 'Council Presidency')
->assertSet('selectedFilter', 'Council Presidency')
->assertDispatched('filterChanged', filter: 'Council Presidency');

Livewire::test(PartnerContentComponent::class)
->dispatch('filterChanged', filter: 'Council Presidency')
->assertSet('filter', 'Council Presidency')
->assertSee('Council President');

Livewire::test(PartnerContentComponent::class)
->dispatch('filterChanged', filter: 'EU Code Week Supporters')
->assertSet('filter', 'EU Code Week Supporters');
}
}
Loading