Skip to content

Commit a9b193d

Browse files
committed
refactor: extract WithIndexFiltering trait from 8 index components
1 parent d619e90 commit a9b193d

9 files changed

Lines changed: 70 additions & 217 deletions

File tree

app/Livewire/Albums/AlbumIndex.php

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use App\Enums\CollectionStatus;
88
use App\Livewire\Concerns\WithAccentInsensitiveSearch;
9+
use App\Livewire\Concerns\WithIndexFiltering;
910
use App\Models\Album;
1011
use Illuminate\Support\Facades\Auth;
1112
use Livewire\Component;
@@ -14,6 +15,7 @@
1415
class AlbumIndex extends Component
1516
{
1617
use WithAccentInsensitiveSearch;
18+
use WithIndexFiltering;
1719
use WithPagination;
1820

1921
public string $search = '';
@@ -52,30 +54,6 @@ public function updatingStatus(): void
5254
$this->resetPage();
5355
}
5456

55-
public function setViewMode(string $mode): void
56-
{
57-
$this->viewMode = in_array($mode, ['gallery', 'list']) ? $mode : 'gallery';
58-
}
59-
60-
public function sort(string $column): void
61-
{
62-
if ($this->sortBy === $column) {
63-
$this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc';
64-
} else {
65-
$this->sortBy = $column;
66-
$this->sortDirection = 'asc';
67-
}
68-
}
69-
70-
private function safeSortDirection(): string
71-
{
72-
return $this->sortDirection === 'asc' ? 'asc' : 'desc';
73-
}
74-
75-
private function safeSortBy(): string
76-
{
77-
return in_array($this->sortBy, self::ALLOWED_SORT_COLUMNS, true) ? $this->sortBy : 'updated_at';
78-
}
7957

8058
public function deleteAlbum(Album $album): void
8159
{

app/Livewire/Anime/AnimeIndex.php

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use App\Enums\WatchingStatus;
88
use App\Livewire\Concerns\WithAccentInsensitiveSearch;
9+
use App\Livewire\Concerns\WithIndexFiltering;
910
use App\Models\Anime;
1011
use Illuminate\Support\Facades\Auth;
1112
use Illuminate\Support\Facades\DB;
@@ -15,6 +16,7 @@
1516
class AnimeIndex extends Component
1617
{
1718
use WithAccentInsensitiveSearch;
19+
use WithIndexFiltering;
1820
use WithPagination;
1921

2022
public string $search = '';
@@ -73,30 +75,6 @@ public function updatingMediaType(): void
7375
$this->resetPage();
7476
}
7577

76-
public function setViewMode(string $mode): void
77-
{
78-
$this->viewMode = in_array($mode, ['gallery', 'list']) ? $mode : 'gallery';
79-
}
80-
81-
public function sort(string $column): void
82-
{
83-
if ($this->sortBy === $column) {
84-
$this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc';
85-
} else {
86-
$this->sortBy = $column;
87-
$this->sortDirection = 'asc';
88-
}
89-
}
90-
91-
private function safeSortDirection(): string
92-
{
93-
return $this->sortDirection === 'asc' ? 'asc' : 'desc';
94-
}
95-
96-
private function safeSortBy(): string
97-
{
98-
return in_array($this->sortBy, self::ALLOWED_SORT_COLUMNS, true) ? $this->sortBy : 'updated_at';
99-
}
10078

10179
public function deleteAnime(Anime $anime): void
10280
{
@@ -151,11 +129,6 @@ public function getStatuses(): array
151129
return WatchingStatus::cases();
152130
}
153131

154-
public function paginationView(): string
155-
{
156-
return 'livewire.custom-pagination';
157-
}
158-
159132
public function render()
160133
{
161134
$perPage = $this->viewMode === 'list' ? 25 : 18;

app/Livewire/BoardGames/BoardGameIndex.php

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use App\Enums\OwnershipStatus;
88
use App\Enums\PlayingStatus;
99
use App\Livewire\Concerns\WithAccentInsensitiveSearch;
10+
use App\Livewire\Concerns\WithIndexFiltering;
1011
use App\Models\BoardGame;
1112
use Illuminate\Support\Facades\Auth;
1213
use Livewire\Component;
@@ -15,6 +16,7 @@
1516
class BoardGameIndex extends Component
1617
{
1718
use WithAccentInsensitiveSearch;
19+
use WithIndexFiltering;
1820
use WithPagination;
1921

2022
public string $search = '';
@@ -70,30 +72,6 @@ public function updatingGenre(): void
7072
$this->resetPage();
7173
}
7274

73-
public function setViewMode(string $mode): void
74-
{
75-
$this->viewMode = in_array($mode, ['gallery', 'list']) ? $mode : 'gallery';
76-
}
77-
78-
public function sort(string $column): void
79-
{
80-
if ($this->sortBy === $column) {
81-
$this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc';
82-
} else {
83-
$this->sortBy = $column;
84-
$this->sortDirection = 'asc';
85-
}
86-
}
87-
88-
private function safeSortDirection(): string
89-
{
90-
return $this->sortDirection === 'asc' ? 'asc' : 'desc';
91-
}
92-
93-
private function safeSortBy(): string
94-
{
95-
return in_array($this->sortBy, self::ALLOWED_SORT_COLUMNS, true) ? $this->sortBy : 'updated_at';
96-
}
9775

9876
public function deleteBoardGame(BoardGame $boardGame): void
9977
{

app/Livewire/Books/BookIndex.php

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use App\Enums\ReadingStatus;
88
use App\Livewire\Concerns\WithAccentInsensitiveSearch;
9+
use App\Livewire\Concerns\WithIndexFiltering;
910
use App\Models\Book;
1011
use Illuminate\Support\Facades\Auth;
1112
use Illuminate\Support\Facades\DB;
@@ -15,6 +16,7 @@
1516
class BookIndex extends Component
1617
{
1718
use WithAccentInsensitiveSearch;
19+
use WithIndexFiltering;
1820
use WithPagination;
1921

2022
public string $search = '';
@@ -73,30 +75,6 @@ public function clearTag(): void
7375
$this->resetPage();
7476
}
7577

76-
public function setViewMode(string $mode): void
77-
{
78-
$this->viewMode = in_array($mode, ['gallery', 'list']) ? $mode : 'gallery';
79-
}
80-
81-
public function sort(string $column): void
82-
{
83-
if ($this->sortBy === $column) {
84-
$this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc';
85-
} else {
86-
$this->sortBy = $column;
87-
$this->sortDirection = 'asc';
88-
}
89-
}
90-
91-
private function safeSortDirection(): string
92-
{
93-
return $this->sortDirection === 'asc' ? 'asc' : 'desc';
94-
}
95-
96-
private function safeSortBy(): string
97-
{
98-
return in_array($this->sortBy, self::ALLOWED_SORT_COLUMNS, true) ? $this->sortBy : 'updated_at';
99-
}
10078

10179
public function updateStatus(Book $book, string $status): void
10280
{
@@ -177,11 +155,6 @@ public function getStatuses(): array
177155
return ReadingStatus::cases();
178156
}
179157

180-
public function paginationView(): string
181-
{
182-
return 'livewire.custom-pagination';
183-
}
184-
185158
public function render()
186159
{
187160
$perPage = $this->viewMode === 'list' ? 25 : 18;

app/Livewire/Comics/ComicIndex.php

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use App\Enums\ReadingStatus;
88
use App\Livewire\Concerns\WithAccentInsensitiveSearch;
9+
use App\Livewire\Concerns\WithIndexFiltering;
910
use App\Models\Comic;
1011
use Illuminate\Support\Facades\Auth;
1112
use Illuminate\Support\Facades\DB;
@@ -15,6 +16,7 @@
1516
class ComicIndex extends Component
1617
{
1718
use WithAccentInsensitiveSearch;
19+
use WithIndexFiltering;
1820
use WithPagination;
1921

2022
public string $search = '';
@@ -65,30 +67,6 @@ public function updatingPublisher(): void
6567
$this->resetPage();
6668
}
6769

68-
public function setViewMode(string $mode): void
69-
{
70-
$this->viewMode = in_array($mode, ['gallery', 'list']) ? $mode : 'gallery';
71-
}
72-
73-
public function sort(string $column): void
74-
{
75-
if ($this->sortBy === $column) {
76-
$this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc';
77-
} else {
78-
$this->sortBy = $column;
79-
$this->sortDirection = 'asc';
80-
}
81-
}
82-
83-
private function safeSortDirection(): string
84-
{
85-
return $this->sortDirection === 'asc' ? 'asc' : 'desc';
86-
}
87-
88-
private function safeSortBy(): string
89-
{
90-
return in_array($this->sortBy, self::ALLOWED_SORT_COLUMNS, true) ? $this->sortBy : 'updated_at';
91-
}
9270

9371
public function updateStatus(Comic $comic, string $status): void
9472
{
@@ -146,11 +124,6 @@ public function deleteSelected(): void
146124
session()->flash('message', "{$count} comic(s) deleted successfully.");
147125
}
148126

149-
public function paginationView(): string
150-
{
151-
return 'livewire.custom-pagination';
152-
}
153-
154127
public function render()
155128
{
156129
$perPage = $this->viewMode === 'list' ? 25 : 18;
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Livewire\Concerns;
6+
7+
/**
8+
* Shared index component behavior for search, sort, view mode, and pagination.
9+
*
10+
* Using classes must define:
11+
* - private const ALLOWED_SORT_COLUMNS (string[])
12+
* - public string $sortBy
13+
* - public string $sortDirection
14+
* - public string $viewMode
15+
*/
16+
trait WithIndexFiltering
17+
{
18+
public function sort(string $column): void
19+
{
20+
if ($this->sortBy === $column) {
21+
$this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc';
22+
} else {
23+
$this->sortBy = $column;
24+
$this->sortDirection = 'asc';
25+
}
26+
}
27+
28+
protected function safeSortDirection(): string
29+
{
30+
return $this->sortDirection === 'asc' ? 'asc' : 'desc';
31+
}
32+
33+
protected function safeSortBy(): string
34+
{
35+
$default = defined('static::DEFAULT_SORT_COLUMN') ? static::DEFAULT_SORT_COLUMN : 'updated_at';
36+
37+
return in_array($this->sortBy, self::ALLOWED_SORT_COLUMNS, true) ? $this->sortBy : $default;
38+
}
39+
40+
public function setViewMode(string $mode): void
41+
{
42+
$default = defined('static::DEFAULT_VIEW_MODE') ? static::DEFAULT_VIEW_MODE : 'gallery';
43+
$this->viewMode = in_array($mode, ['gallery', 'list']) ? $mode : $default;
44+
}
45+
46+
public function paginationView(): string
47+
{
48+
return 'livewire.custom-pagination';
49+
}
50+
}

app/Livewire/Concerts/ConcertIndex.php

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use App\Enums\ListeningStatus;
88
use App\Livewire\Concerns\WithAccentInsensitiveSearch;
9+
use App\Livewire\Concerns\WithIndexFiltering;
910
use App\Models\Concert;
1011
use Illuminate\Support\Facades\Auth;
1112
use Livewire\Component;
@@ -14,8 +15,13 @@
1415
class ConcertIndex extends Component
1516
{
1617
use WithAccentInsensitiveSearch;
18+
use WithIndexFiltering;
1719
use WithPagination;
1820

21+
private const DEFAULT_VIEW_MODE = 'list';
22+
23+
private const DEFAULT_SORT_COLUMN = 'event_date';
24+
1925
public string $search = '';
2026

2127
public string $status = '';
@@ -52,30 +58,6 @@ public function updatingStatus(): void
5258
$this->resetPage();
5359
}
5460

55-
public function setViewMode(string $mode): void
56-
{
57-
$this->viewMode = in_array($mode, ['gallery', 'list']) ? $mode : 'list';
58-
}
59-
60-
public function sort(string $column): void
61-
{
62-
if ($this->sortBy === $column) {
63-
$this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc';
64-
} else {
65-
$this->sortBy = $column;
66-
$this->sortDirection = 'asc';
67-
}
68-
}
69-
70-
private function safeSortDirection(): string
71-
{
72-
return $this->sortDirection === 'asc' ? 'asc' : 'desc';
73-
}
74-
75-
private function safeSortBy(): string
76-
{
77-
return in_array($this->sortBy, self::ALLOWED_SORT_COLUMNS, true) ? $this->sortBy : 'event_date';
78-
}
7961

8062
public function deleteConcert(Concert $concert): void
8163
{

0 commit comments

Comments
 (0)