refactor: extract status badge into reusable component
This commit is contained in:
@@ -0,0 +1,37 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { ReportStatus } from '~/types/api'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
status: ReportStatus
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<Props>()
|
||||||
|
|
||||||
|
const badgeConfig = computed(() => {
|
||||||
|
const config: Record<ReportStatus, { color: string, text: string, icon: string }> = {
|
||||||
|
OPEN: { color: 'info', text: 'Aperta', icon: 'it-info-circle' },
|
||||||
|
UNDER_REVIEW: { color: 'warning', text: 'In Revisione', icon: 'it-clock' },
|
||||||
|
ASSIGNED: { color: 'primary', text: 'Assegnata', icon: 'it-user' },
|
||||||
|
IN_PROGRESS: { color: 'primary', text: 'In Lavorazione', icon: 'it-settings' },
|
||||||
|
RESOLVED: { color: 'success', text: 'Risolta', icon: 'it-check-circle' },
|
||||||
|
REJECTED: { color: 'danger', text: 'Rifiutata', icon: 'it-close-circle' },
|
||||||
|
CLOSED: { color: 'secondary', text: 'Chiusa', icon: 'it-locked' }
|
||||||
|
}
|
||||||
|
|
||||||
|
return config[props.status] || { color: 'secondary', text: props.status, icon: 'it-info-circle' }
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<span class="badge badge-pill rounded-pill d-inline-flex align-items-center gap-1" :class="`bg-${badgeConfig.color}`">
|
||||||
|
<BIIcon :name="badgeConfig.icon" size="xs" color="white" />
|
||||||
|
{{ badgeConfig.text }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.badge {
|
||||||
|
font-weight: 600;
|
||||||
|
padding: 0.35em 0.65em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -66,22 +66,6 @@ const handlePageChange = (newPage: number) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Helpers grafici
|
// Helpers grafici
|
||||||
const getStatusColor = (status: string): string => {
|
|
||||||
const colors: Record<string, string> = {
|
|
||||||
OPEN: 'primary', UNDER_REVIEW: 'info', ASSIGNED: 'warning',
|
|
||||||
IN_PROGRESS: 'warning', RESOLVED: 'success', REJECTED: 'danger', CLOSED: 'secondary',
|
|
||||||
}
|
|
||||||
return colors[status] || 'secondary'
|
|
||||||
}
|
|
||||||
|
|
||||||
const getStatusLabel = (status: string): string => {
|
|
||||||
const labels: Record<string, string> = {
|
|
||||||
OPEN: 'Aperta', UNDER_REVIEW: 'In revisione', ASSIGNED: 'Assegnata',
|
|
||||||
IN_PROGRESS: 'In corso', RESOLVED: 'Risolta', REJECTED: 'Rifiutata', CLOSED: 'Chiusa',
|
|
||||||
}
|
|
||||||
return labels[status] || status
|
|
||||||
}
|
|
||||||
|
|
||||||
const formatDate = (dateString?: string): string => {
|
const formatDate = (dateString?: string): string => {
|
||||||
if (!dateString) return ''
|
if (!dateString) return ''
|
||||||
return new Date(dateString).toLocaleDateString('it-IT', {
|
return new Date(dateString).toLocaleDateString('it-IT', {
|
||||||
@@ -220,9 +204,7 @@ const formatDate = (dateString?: string): string => {
|
|||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="small">
|
<td class="small">
|
||||||
<span class="badge" :class="`bg-${getStatusColor(report.status)}`">
|
<StatusBadge :status="report.status" />
|
||||||
{{ getStatusLabel(report.status) }}
|
|
||||||
</span>
|
|
||||||
</td>
|
</td>
|
||||||
<td class="small text-muted">{{ formatDate(report.created_at) }}</td>
|
<td class="small text-muted">{{ formatDate(report.created_at) }}</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
@@ -235,10 +217,13 @@ const formatDate = (dateString?: string): string => {
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Paginazione Client-Side (Opzionale: implementare se hai molti dati) -->
|
<Pagination
|
||||||
<div v-if="totalFiltered > perPage" class="d-flex justify-content-center mt-4">
|
v-if="totalFiltered > perPage"
|
||||||
<!-- Qui potresti inserire un componente Pagination se ne hai uno -->
|
:current-page="page"
|
||||||
</div>
|
:per-page="perPage"
|
||||||
|
:total-items="totalFiltered"
|
||||||
|
@page-change="handlePageChange"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ const handleTakeReport = async (id: number) => {
|
|||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<h6 class="mb-1">{{ report.address }}</h6>
|
<h6 class="mb-1">{{ report.address }}</h6>
|
||||||
<span class="badge bg-warning text-dark">{{ report.status }}</span>
|
<StatusBadge :status="report.status" />
|
||||||
</div>
|
</div>
|
||||||
<BIIcon name="it-chevron-right" size="sm" color="primary" />
|
<BIIcon name="it-chevron-right" size="sm" color="primary" />
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
|
|||||||
@@ -41,34 +41,6 @@ const isFlagging = ref(false)
|
|||||||
const selectedMediaIndex = ref(0)
|
const selectedMediaIndex = ref(0)
|
||||||
const isGalleryOpen = ref(false)
|
const isGalleryOpen = ref(false)
|
||||||
|
|
||||||
// Status badge color
|
|
||||||
const getStatusColor = (status: string): string => {
|
|
||||||
const colors: Record<string, string> = {
|
|
||||||
OPEN: 'primary',
|
|
||||||
UNDER_REVIEW: 'info',
|
|
||||||
ASSIGNED: 'warning',
|
|
||||||
IN_PROGRESS: 'warning',
|
|
||||||
RESOLVED: 'success',
|
|
||||||
REJECTED: 'danger',
|
|
||||||
CLOSED: 'secondary',
|
|
||||||
}
|
|
||||||
return colors[status] || 'secondary'
|
|
||||||
}
|
|
||||||
|
|
||||||
// Status label italiano
|
|
||||||
const getStatusLabel = (status: string): string => {
|
|
||||||
const labels: Record<string, string> = {
|
|
||||||
OPEN: 'Aperta',
|
|
||||||
UNDER_REVIEW: 'In revisione',
|
|
||||||
ASSIGNED: 'Assegnata',
|
|
||||||
IN_PROGRESS: 'In corso',
|
|
||||||
RESOLVED: 'Risolta',
|
|
||||||
REJECTED: 'Rifiutata',
|
|
||||||
CLOSED: 'Chiusa',
|
|
||||||
}
|
|
||||||
return labels[status] || status
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invia messaggio
|
// Invia messaggio
|
||||||
const handleSendMessage = async () => {
|
const handleSendMessage = async () => {
|
||||||
if (!newMessage.value.trim()) return
|
if (!newMessage.value.trim()) return
|
||||||
@@ -145,9 +117,7 @@ const formatDate = (dateString: string): string => {
|
|||||||
<div class="col-12 col-md-8">
|
<div class="col-12 col-md-8">
|
||||||
<h1 class="h3 font-weight-bold mb-2">{{ report.category_name }}</h1>
|
<h1 class="h3 font-weight-bold mb-2">{{ report.category_name }}</h1>
|
||||||
<div class="d-flex align-items-center gap-3">
|
<div class="d-flex align-items-center gap-3">
|
||||||
<span class="badge" :class="`bg-${getStatusColor(report.status)}`">
|
<StatusBadge :status="report.status" />
|
||||||
{{ getStatusLabel(report.status) }}
|
|
||||||
</span>
|
|
||||||
<small class="text-muted">
|
<small class="text-muted">
|
||||||
<BIIcon name="it-clock" size="xs" class="me-1" />
|
<BIIcon name="it-clock" size="xs" class="me-1" />
|
||||||
Creata il {{ formatDate(report.created_at) }}
|
Creata il {{ formatDate(report.created_at) }}
|
||||||
@@ -230,8 +200,10 @@ const formatDate = (dateString: string): string => {
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex-grow-1">
|
<div class="flex-grow-1">
|
||||||
<small class="text-muted">{{ formatDate(item.created_at) }}</small>
|
<small class="text-muted">{{ formatDate(item.created_at) }}</small>
|
||||||
<div class="small font-weight-semibold">
|
<div class="small font-weight-semibold d-flex align-items-center gap-2 mt-1">
|
||||||
{{ getStatusLabel(item.old_status) }} → {{ getStatusLabel(item.new_status) }}
|
<StatusBadge :status="item.old_status" />
|
||||||
|
<BIIcon name="it-arrow-right" size="xs" />
|
||||||
|
<StatusBadge :status="item.new_status" />
|
||||||
</div>
|
</div>
|
||||||
<small v-if="item.note" class="text-muted d-block">{{ item.note }}</small>
|
<small v-if="item.note" class="text-muted d-block">{{ item.note }}</small>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user