Files
sentry-toolkit/inertia/pages/Replays/Index.vue
2025-05-20 11:23:35 -04:00

120 lines
3.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="m-5">
<h1 class="text-2xl font-bold mb-4">Replays</h1>
<table class="w-full border text-left">
<thead>
<tr class="bg-gray-100">
<th class="p-2">ID</th>
<th class="p-2">Email</th>
<th class="p-2">Date</th>
<th class="p-2">Location</th>
</tr>
</thead>
<tbody>
<tr v-for="replay in data.replays" :key="replay.id" class="border-t">
<td class="p-2">{{ replay.id }}</td>
<td class="p-2">{{ replay.user.email ?? replay.user.display_name }}</td>
<td class="p-2">{{ replay.finished_at }}</td>
<td class="p-2">{{ replay.user.geo ? `${replay.user.geo.city} ${replay.user.geo.subdivision}, ${replay.user.geo.region}` : 'unknown' }}</td>
</tr>
</tbody>
</table>
<!-- Pagination -->
<div class="mt-4 flex flex-wrap items-center gap-2" v-if="data.meta && data.meta.links && data.meta.links.length > 1">
<!-- First -->
<Link
v-if="firstPageUrl && !isFirstPage"
:href="firstPageUrl"
class="px-3 py-1 border rounded text-sm"
>
« First
</Link>
<!-- Previous -->
<Link
v-if="prevPageUrl"
:href="prevPageUrl"
class="px-3 py-1 border rounded text-sm"
>
Prev
</Link>
<!-- Page Numbers (windowed) -->
<template v-for="link in paginatedLinks" :key="link.label">
<component
:is="link.url ? Link : 'span'"
:href="link.url"
class="px-3 py-1 border rounded text-sm"
:class="{
'font-bold bg-gray-300': link.active,
'text-gray-400 cursor-not-allowed': !link.url
}"
>
<span v-html="link.label" />
</component>
</template>
<!-- Next -->
<Link
v-if="nextPageUrl"
:href="nextPageUrl"
class="px-3 py-1 border rounded text-sm"
>
Next
</Link>
<!-- Last -->
<Link
v-if="lastPageUrl && !isLastPage"
:href="lastPageUrl"
class="px-3 py-1 border rounded text-sm"
>
Last »
</Link>
</div>
</div>
</template>
<script setup>
import { computed } from 'vue'
import { Link } from '@inertiajs/vue3'
const props = defineProps({
data: Object
})
// Core pagination values
const links = computed(() => props.data.meta.links || [])
const currentIndex = computed(() => links.value.findIndex(link => link.active))
const maxVisible = 10
const half = Math.floor(maxVisible / 2)
const paginatedLinks = computed(() => {
const total = links.value.length
if (total <= maxVisible) return links.value
let start = Math.max(currentIndex.value - half, 0)
let end = start + maxVisible
if (end > total) {
end = total
start = Math.max(0, end - maxVisible)
}
return links.value.slice(start, end)
})
// Navigation links
const firstPageUrl = computed(() => links.value[1]?.url) // usually index 1 is page=1
const prevPageUrl = computed(() => links.value[currentIndex.value - 1]?.url)
const nextPageUrl = computed(() => links.value[currentIndex.value + 1]?.url)
const lastPageUrl = computed(() => links.value[links.value.length - 2]?.url) // last item is "Next »", second-last is last numbered
const isFirstPage = computed(() => links.value[currentIndex.value]?.label === '1')
const isLastPage = computed(() => links.value[currentIndex.value]?.label === props.data.meta.last_page)
</script>