diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 37e7337..e5f9503 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -2,7 +2,8 @@ "permissions": { "allow": [ "Bash(php artisan *)", - "Bash(vendor/bin/pint --dirty --format agent)" + "Bash(vendor/bin/pint --dirty --format agent)", + "mcp__laravel-boost__search-docs" ] } } diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index e0ef0c5..6675d8a 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -3,12 +3,17 @@ namespace App\Http\Controllers; use App\Models\User; +use Illuminate\Http\Request; class UserController extends Controller { - public function index() + public function index(Request $request) { - $users = User::orderBy('name')->get(); + $users = User::orderBy('name')->paginate(10); + + if ($request->ajax()) { + return view('users._table', compact('users')); + } return view('users.index', compact('users')); } diff --git a/resources/views/users/_table.blade.php b/resources/views/users/_table.blade.php new file mode 100644 index 0000000..93b983a --- /dev/null +++ b/resources/views/users/_table.blade.php @@ -0,0 +1,34 @@ + + + + + + + + + + + @foreach ($users as $user) + + + + + + + @endforeach + + @if ($users->isEmpty()) + + + + @endif + +
#{{ __('Name') }}{{ __('Email') }}{{ __('Joined') }}
{{ $users->firstItem() + $loop->index }}{{ $user->name }}{{ $user->email }}{{ $user->created_at->format('d M Y') }}
+ {{ __('No users found.') }} +
+ +@if ($users->hasPages()) +
+ {{ $users->links() }} +
+@endif diff --git a/resources/views/users/index.blade.php b/resources/views/users/index.blade.php index 0676ab5..9e63aaa 100644 --- a/resources/views/users/index.blade.php +++ b/resources/views/users/index.blade.php @@ -8,35 +8,33 @@
-
- - - - - - - - - - - @foreach ($users as $index => $user) - - - - - - - @endforeach +
+
+ {{ __('Loading...') }} +
- @if ($users->isEmpty()) -
- - - @endif - -
#{{ __('Name') }}{{ __('Email') }}{{ __('Joined') }}
{{ $index + 1 }}{{ $user->name }}{{ $user->email }}{{ $user->created_at->format('d M Y') }}
- {{ __('No users found.') }} -
+
+ @include('users._table') +
diff --git a/tests/Feature/UserIndexTest.php b/tests/Feature/UserIndexTest.php index ab41f9a..a1ef24b 100644 --- a/tests/Feature/UserIndexTest.php +++ b/tests/Feature/UserIndexTest.php @@ -15,11 +15,33 @@ test('authenticated users can view the users page', function () { ->assertViewIs('users.index'); }); -test('users page lists all users', function () { - $users = User::factory()->count(3)->create(); +test('users page passes paginated users to view', function () { + $user = User::factory()->create(); - $this->actingAs($users->first()) + $this->actingAs($user) ->get('/users') ->assertOk() - ->assertViewHas('users', fn ($viewUsers) => $viewUsers->count() === User::count()); + ->assertViewHas('users'); +}); + +test('ajax request returns table partial', function () { + $user = User::factory()->create(); + + $this->actingAs($user) + ->withHeader('X-Requested-With', 'XMLHttpRequest') + ->get('/users') + ->assertOk() + ->assertViewIs('users._table'); +}); + +test('ajax pagination returns correct page', function () { + $user = User::factory()->create(); + User::factory()->count(15)->create(); + + $this->actingAs($user) + ->withHeader('X-Requested-With', 'XMLHttpRequest') + ->get('/users?page=2') + ->assertOk() + ->assertViewIs('users._table') + ->assertViewHas('users', fn ($users) => $users->currentPage() === 2); });