diff --git a/app/Http/Controllers/PhotosController.php b/app/Http/Controllers/PhotosController.php
index 11d9f6c1..2ff4687b 100644
--- a/app/Http/Controllers/PhotosController.php
+++ b/app/Http/Controllers/PhotosController.php
@@ -16,7 +16,7 @@ public function index()
/** @var User $user */
$user = auth()->user();
- $photos = $user->photos()->latest()->paginate();
+ $photos = $user->photos()->latest('id')->paginate(12);
$photos->getCollection()->transform(function (Photo $photo) {
$photo->append('full_path');
@@ -45,6 +45,7 @@ public function show(Photo $photo)
'photoId' => $photo->id,
'items' => Item::query()->orderBy('name')->get(),
'tags' => $tags,
+ 'nextPhotoUrl' => $this->getNextPhotoUrl($photo),
]);
}
@@ -61,4 +62,20 @@ public function show(Photo $photo)
'items' => $items,
];
}
+
+ private function getNextPhotoUrl(Photo $photo): ?string
+ {
+ $nextPhoto = Photo::query()
+ ->where('user_id', $photo->user_id)
+ ->whereDoesntHave('items')
+ ->where('id', '<', $photo->id)
+ ->orderByDesc('id')
+ ->first();
+
+ if (! $nextPhoto) {
+ return null;
+ }
+
+ return route('photos.show', $nextPhoto);
+ }
}
diff --git a/resources/js/Pages/Photo/Show.vue b/resources/js/Pages/Photo/Show.vue
index 8032fd85..f950afa2 100644
--- a/resources/js/Pages/Photo/Show.vue
+++ b/resources/js/Pages/Photo/Show.vue
@@ -2,11 +2,14 @@
import AppLayout from '@/Layouts/AppLayout.vue';
import {onMounted, ref} from "vue";
import PhotoItem from "@/Pages/Photo/PhotoItem.vue";
+import {Link} from "@inertiajs/vue3";
+import PrimaryButton from "@/Components/PrimaryButton.vue";
const props = defineProps({
photoId: Number,
items: Array,
- tags: Array,
+ tags: Object,
+ nextPhotoUrl: String,
});
const photo = ref(null);
@@ -81,8 +84,16 @@ const toggleItemPickedUp = (photoItemId) => {
+
+
+
Next Photo
+
+
+
All Photos
+
+
diff --git a/routes/web.php b/routes/web.php
index 5977ffd2..472115b8 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -46,7 +46,7 @@
})->name('docs');
Route::get('/my-photos', [PhotosController::class, 'index'])->name('my-photos');
- Route::get('/photos/{photo}', [PhotosController::class, 'show']);
+ Route::get('/photos/{photo}', [PhotosController::class, 'show'])->name('photos.show');
Route::post('/photos/{photo}/tags', [PhotoTagsController::class, 'store']);
Route::delete('/photos/{photo}/tags/{tag}', [PhotoTagsController::class, 'destroy']);
diff --git a/tests/Feature/Photos/ShowPhotoTest.php b/tests/Feature/Photos/ShowPhotoTest.php
index 5bf93158..bb3dd804 100644
--- a/tests/Feature/Photos/ShowPhotoTest.php
+++ b/tests/Feature/Photos/ShowPhotoTest.php
@@ -25,7 +25,7 @@
['name' => 'C material'],
)->create(['tag_type_id' => $material->id]);
- $response = $this->get("/photos/{$photo->id}");
+ $response = $this->get(route('photos.show', $photo));
$response->assertOk();
@@ -40,6 +40,32 @@
);
});
+test('a user can see the next untagged photo link', function () {
+ $this->actingAs($user = User::factory()->create());
+ $photo = Photo::factory()->for($user)->create();
+ $untaggedPhoto = Photo::factory()->for($user)->create();
+
+ $response = $this->get(route('photos.show', $photo));
+
+ $response->assertOk();
+ $response->assertInertia(fn (AssertableInertia $page) => $page
+ ->where('nextPhotoUrl', route('photos.show', $untaggedPhoto))
+ );
+});
+
+test('a user can not see the next untagged photo link if there are no more untagged photos', function () {
+ $this->actingAs($user = User::factory()->create());
+ $photo = Photo::factory()->for($user)->create();
+ $taggedPhoto = Photo::factory()->for($user)->create();
+ $item = Item::factory()->create();
+ $taggedPhoto->items()->sync($item);
+
+ $response = $this->get(route('photos.show', $photo));
+
+ $response->assertOk();
+ $response->assertInertia(fn (AssertableInertia $page) => $page->where('nextPhotoUrl', null));
+});
+
test('a user can see a photo', function () {
$this->actingAs($user = User::factory()->create());
$photo = Photo::factory()->for($user)->create();
@@ -51,7 +77,7 @@
'tag_id' => $tag->id,
]);
- $response = $this->getJson("/photos/{$photo->id}");
+ $response = $this->getJson(route('photos.show', $photo));
$response->assertOk();
$response->assertJson(fn (AssertableJson $json) => $json