Makes the photo review process easier
This commit is contained in:
@@ -14,12 +14,13 @@
|
||||
if (!auth.isAdmin) push('/')
|
||||
})
|
||||
|
||||
type PhotoWithTeam = PhotoResponse & { teamName: string }
|
||||
|
||||
let hunt = $state<HuntResponse | null>(null)
|
||||
let teams = $state<TeamResponse[]>([])
|
||||
let items = $state<ItemResponse[]>([])
|
||||
let selectedTeam = $state<TeamResponse | null>(null)
|
||||
let selectedItem = $state<ItemResponse | null>(null)
|
||||
let photos = $state<PhotoResponse[]>([])
|
||||
let photos = $state<PhotoWithTeam[]>([])
|
||||
let loading = $state(true)
|
||||
let photosLoading = $state(false)
|
||||
let error = $state('')
|
||||
@@ -32,29 +33,28 @@
|
||||
hunt = h
|
||||
teams = t
|
||||
items = i
|
||||
// Pre-select team from query string if provided
|
||||
const qs = new URLSearchParams(router.querystring ?? '')
|
||||
const preTeam = qs.get('teamId')
|
||||
if (preTeam) {
|
||||
selectedTeam = t.find(x => x.id === preTeam) ?? null
|
||||
}
|
||||
})
|
||||
.catch(e => { error = e instanceof Error ? e.message : 'Failed to load' })
|
||||
.finally(() => { loading = false })
|
||||
})
|
||||
|
||||
$effect(() => {
|
||||
if (selectedTeam && selectedItem) {
|
||||
if (selectedItem) {
|
||||
photosLoading = true
|
||||
photos = []
|
||||
apiGetItemPhotos(params.huntId, selectedTeam.id, selectedItem.id)
|
||||
.then(p => { photos = p })
|
||||
Promise.all(
|
||||
teams.map(team =>
|
||||
apiGetItemPhotos(params.huntId, team.id, selectedItem!.id)
|
||||
.then(ps => ps.map(p => ({ ...p, teamName: team.name })))
|
||||
)
|
||||
)
|
||||
.then(results => { photos = results.flat() })
|
||||
.catch(e => { error = e instanceof Error ? e.message : 'Failed to load photos' })
|
||||
.finally(() => { photosLoading = false })
|
||||
}
|
||||
})
|
||||
|
||||
async function review(photo: PhotoResponse, status: 'APPROVED' | 'REJECTED') {
|
||||
async function review(photo: PhotoWithTeam, status: 'APPROVED' | 'REJECTED') {
|
||||
reviewing = photo.id
|
||||
try {
|
||||
await apiReviewPhoto(photo.id, status)
|
||||
@@ -82,24 +82,6 @@
|
||||
{#if loading}
|
||||
<LoadingSpinner />
|
||||
{:else}
|
||||
<!-- Team selector -->
|
||||
<div class="mb-4">
|
||||
<p class="text-sm font-medium text-base-content/60 mb-2">Select Team</p>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
{#each teams as team}
|
||||
<button
|
||||
class="btn btn-sm"
|
||||
class:btn-primary={selectedTeam?.id === team.id}
|
||||
class:btn-outline={selectedTeam?.id !== team.id}
|
||||
onclick={() => { selectedTeam = team; selectedItem = null; photos = [] }}
|
||||
>
|
||||
{team.name}
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if selectedTeam}
|
||||
<!-- Item selector -->
|
||||
<div class="mb-4">
|
||||
<p class="text-sm font-medium text-base-content/60 mb-2">Select Item</p>
|
||||
@@ -116,9 +98,8 @@
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if selectedTeam && selectedItem}
|
||||
{#if selectedItem}
|
||||
{#if photosLoading}
|
||||
<LoadingSpinner />
|
||||
{:else if activePhotos.length === 0}
|
||||
@@ -133,7 +114,7 @@
|
||||
<div class="p-3">
|
||||
<div class="flex items-center justify-between mb-3">
|
||||
<div>
|
||||
<p class="font-semibold">{photo.hunterName}</p>
|
||||
<p class="font-semibold">{photo.hunterName} <span class="text-base-content/50 font-normal">· {photo.teamName}</span></p>
|
||||
<p class="text-xs text-base-content/50">
|
||||
{new Date(photo.photoUploadDateTime).toLocaleString()}
|
||||
</p>
|
||||
|
||||
Reference in New Issue
Block a user