Makes the photo review process easier
This commit is contained in:
@@ -14,12 +14,13 @@
|
|||||||
if (!auth.isAdmin) push('/')
|
if (!auth.isAdmin) push('/')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
type PhotoWithTeam = PhotoResponse & { teamName: string }
|
||||||
|
|
||||||
let hunt = $state<HuntResponse | null>(null)
|
let hunt = $state<HuntResponse | null>(null)
|
||||||
let teams = $state<TeamResponse[]>([])
|
let teams = $state<TeamResponse[]>([])
|
||||||
let items = $state<ItemResponse[]>([])
|
let items = $state<ItemResponse[]>([])
|
||||||
let selectedTeam = $state<TeamResponse | null>(null)
|
|
||||||
let selectedItem = $state<ItemResponse | null>(null)
|
let selectedItem = $state<ItemResponse | null>(null)
|
||||||
let photos = $state<PhotoResponse[]>([])
|
let photos = $state<PhotoWithTeam[]>([])
|
||||||
let loading = $state(true)
|
let loading = $state(true)
|
||||||
let photosLoading = $state(false)
|
let photosLoading = $state(false)
|
||||||
let error = $state('')
|
let error = $state('')
|
||||||
@@ -32,29 +33,28 @@
|
|||||||
hunt = h
|
hunt = h
|
||||||
teams = t
|
teams = t
|
||||||
items = i
|
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' })
|
.catch(e => { error = e instanceof Error ? e.message : 'Failed to load' })
|
||||||
.finally(() => { loading = false })
|
.finally(() => { loading = false })
|
||||||
})
|
})
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (selectedTeam && selectedItem) {
|
if (selectedItem) {
|
||||||
photosLoading = true
|
photosLoading = true
|
||||||
photos = []
|
photos = []
|
||||||
apiGetItemPhotos(params.huntId, selectedTeam.id, selectedItem.id)
|
Promise.all(
|
||||||
.then(p => { photos = p })
|
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' })
|
.catch(e => { error = e instanceof Error ? e.message : 'Failed to load photos' })
|
||||||
.finally(() => { photosLoading = false })
|
.finally(() => { photosLoading = false })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
async function review(photo: PhotoResponse, status: 'APPROVED' | 'REJECTED') {
|
async function review(photo: PhotoWithTeam, status: 'APPROVED' | 'REJECTED') {
|
||||||
reviewing = photo.id
|
reviewing = photo.id
|
||||||
try {
|
try {
|
||||||
await apiReviewPhoto(photo.id, status)
|
await apiReviewPhoto(photo.id, status)
|
||||||
@@ -82,24 +82,6 @@
|
|||||||
{#if loading}
|
{#if loading}
|
||||||
<LoadingSpinner />
|
<LoadingSpinner />
|
||||||
{:else}
|
{: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 -->
|
<!-- Item selector -->
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<p class="text-sm font-medium text-base-content/60 mb-2">Select Item</p>
|
<p class="text-sm font-medium text-base-content/60 mb-2">Select Item</p>
|
||||||
@@ -116,9 +98,8 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
|
||||||
|
|
||||||
{#if selectedTeam && selectedItem}
|
{#if selectedItem}
|
||||||
{#if photosLoading}
|
{#if photosLoading}
|
||||||
<LoadingSpinner />
|
<LoadingSpinner />
|
||||||
{:else if activePhotos.length === 0}
|
{:else if activePhotos.length === 0}
|
||||||
@@ -133,7 +114,7 @@
|
|||||||
<div class="p-3">
|
<div class="p-3">
|
||||||
<div class="flex items-center justify-between mb-3">
|
<div class="flex items-center justify-between mb-3">
|
||||||
<div>
|
<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">
|
<p class="text-xs text-base-content/50">
|
||||||
{new Date(photo.photoUploadDateTime).toLocaleString()}
|
{new Date(photo.photoUploadDateTime).toLocaleString()}
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
Reference in New Issue
Block a user