119 lines
3.8 KiB
Vue
119 lines
3.8 KiB
Vue
<script setup lang="ts">
|
|
import type { Report } from '~/types/api'
|
|
import { isWithinBariBounds } from '~/utils/bari'
|
|
|
|
definePageMeta({
|
|
middleware: 'auth',
|
|
})
|
|
|
|
useHead({ title: 'Le mie segnalazioni - Visione' })
|
|
|
|
const { getReports } = useReports()
|
|
|
|
const page = ref(1)
|
|
const perPage = ref(10)
|
|
const filterStatus = ref('')
|
|
|
|
const { data: reportsRes, pending } = useAsyncData('citizen-reports-list', () => getReports({}))
|
|
|
|
const reports = computed<Report[]>(() =>
|
|
(reportsRes.value?.reports || []).filter((report) => isWithinBariBounds(report.latitude, report.longitude))
|
|
)
|
|
const filteredReports = computed(() => {
|
|
if (!filterStatus.value) return reports.value
|
|
if (filterStatus.value === 'IN_PROGRESS') {
|
|
return reports.value.filter((report) => report.status === 'IN_PROGRESS' || report.status === 'ASSIGNED')
|
|
}
|
|
return reports.value.filter((report) => report.status === filterStatus.value)
|
|
})
|
|
|
|
const paginatedReports = computed(() => {
|
|
const start = (page.value - 1) * perPage.value
|
|
return filteredReports.value.slice(start, start + perPage.value)
|
|
})
|
|
|
|
const handleStatusFilter = (status: string) => {
|
|
filterStatus.value = status === 'all' ? '' : status
|
|
page.value = 1
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<div class="bg-light border-bottom py-4 mb-4">
|
|
<div class="container">
|
|
<div class="d-flex flex-column flex-md-row justify-content-between align-items-md-center gap-3">
|
|
<div>
|
|
<h1 class="h3 font-weight-bold mb-1">Le mie segnalazioni</h1>
|
|
<p class="text-muted mb-0">Consulta stato, cronologia e conversazioni con gli operatori.</p>
|
|
</div>
|
|
<NuxtLink to="/reports/new" class="btn btn-primary">
|
|
<BIIcon name="it-plus-circle" size="sm" color="white" class="me-2" />
|
|
Nuova segnalazione
|
|
</NuxtLink>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="container mb-5">
|
|
<div class="d-flex flex-wrap gap-2 align-items-center mb-3">
|
|
<div class="btn-group" role="group" aria-label="Filtri segnalazioni">
|
|
<button
|
|
type="button"
|
|
class="btn btn-sm"
|
|
:class="filterStatus === '' ? 'btn-primary' : 'btn-outline-primary'"
|
|
@click="handleStatusFilter('all')"
|
|
>
|
|
Tutte
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="btn btn-sm"
|
|
:class="filterStatus === 'OPEN' ? 'btn-primary' : 'btn-outline-primary'"
|
|
@click="handleStatusFilter('OPEN')"
|
|
>
|
|
Aperte
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="btn btn-sm"
|
|
:class="filterStatus === 'IN_PROGRESS' ? 'btn-primary' : 'btn-outline-primary'"
|
|
@click="handleStatusFilter('IN_PROGRESS')"
|
|
>
|
|
In corso
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="btn btn-sm"
|
|
:class="filterStatus === 'RESOLVED' ? 'btn-primary' : 'btn-outline-primary'"
|
|
@click="handleStatusFilter('RESOLVED')"
|
|
>
|
|
Risolte
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div v-if="pending" class="text-center py-5">
|
|
<div class="spinner-border text-primary" role="status">
|
|
<span class="visually-hidden">Caricamento...</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div v-else-if="filteredReports.length === 0" class="alert alert-info" role="alert">
|
|
Nessuna segnalazione trovata.
|
|
</div>
|
|
|
|
<template v-else>
|
|
<ReportTable :reports="paginatedReports" action-label="Apri segnalazione" />
|
|
<Pagination
|
|
v-if="filteredReports.length > perPage"
|
|
:current-page="page"
|
|
:per-page="perPage"
|
|
:total-items="filteredReports.length"
|
|
@page-change="page = $event"
|
|
/>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
</template>
|