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 @@
+
+
+
+ | # |
+ {{ __('Name') }} |
+ {{ __('Email') }} |
+ {{ __('Joined') }} |
+
+
+
+ @foreach ($users as $user)
+
+ | {{ $users->firstItem() + $loop->index }} |
+ {{ $user->name }} |
+ {{ $user->email }} |
+ {{ $user->created_at->format('d M Y') }} |
+
+ @endforeach
+
+ @if ($users->isEmpty())
+
+ |
+ {{ __('No users found.') }}
+ |
+
+ @endif
+
+
+
+@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 @@
-
-
-
-
- | # |
- {{ __('Name') }} |
- {{ __('Email') }} |
- {{ __('Joined') }} |
-
-
-
- @foreach ($users as $index => $user)
-
- | {{ $index + 1 }} |
- {{ $user->name }} |
- {{ $user->email }} |
- {{ $user->created_at->format('d M Y') }} |
-
- @endforeach
+
+
+ {{ __('Loading...') }}
+
- @if ($users->isEmpty())
-
- |
- {{ __('No users found.') }}
- |
-
- @endif
-
-
+
+ @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);
});