feat(admin): add delete functionality for areas, categories, and teams in admin panel
This commit is contained in:
+58
-18
@@ -9,7 +9,7 @@ definePageMeta({
|
||||
|
||||
useHead({ title: 'Aree - Admin' })
|
||||
|
||||
const { getAreas, createArea, updateArea } = useAdmin()
|
||||
const { getAreas, createArea, updateArea, deleteArea } = useAdmin()
|
||||
const { data: areasRes, pending, refresh } = useAsyncData('admin-areas', () => getAreas())
|
||||
|
||||
const isCreating = ref(false)
|
||||
@@ -20,6 +20,9 @@ const formData = reactive({
|
||||
geojson: ''
|
||||
})
|
||||
const jsonError = ref('')
|
||||
const actionError = ref('')
|
||||
const deletingAreaId = ref<number | null>(null)
|
||||
const areaPendingDelete = ref<any | null>(null)
|
||||
|
||||
// Map variables
|
||||
let map: any = null
|
||||
@@ -29,8 +32,10 @@ const mapPoints = ref<[number, number][]>([])
|
||||
const modalTitle = computed(() => editingAreaId.value ? 'Modifica Area' : 'Nuova Area')
|
||||
const submitLabel = computed(() => editingAreaId.value ? 'Salva Modifiche' : 'Crea Area')
|
||||
const isEditing = computed(() => editingAreaId.value !== null)
|
||||
const areas = computed(() => areasRes.value?.areas || [])
|
||||
|
||||
const openCreateModal = () => {
|
||||
actionError.value = ''
|
||||
editingAreaId.value = null
|
||||
formData.name = ''
|
||||
formData.description = ''
|
||||
@@ -98,6 +103,7 @@ const loadPolygonFromGeoJson = (boundaryGeojson: any) => {
|
||||
}
|
||||
|
||||
const openEditModal = (area: any) => {
|
||||
actionError.value = ''
|
||||
editingAreaId.value = area.id
|
||||
formData.name = area.name || ''
|
||||
formData.description = area.description || ''
|
||||
@@ -218,22 +224,45 @@ const handleCreate = async () => {
|
||||
if (res.ok) {
|
||||
await refresh()
|
||||
closeCreateModal()
|
||||
actionError.value = ''
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Failed to save area', err)
|
||||
alert('Errore durante il salvataggio dell\'area.')
|
||||
actionError.value = 'Errore durante il salvataggio dell\'area.'
|
||||
}
|
||||
}
|
||||
|
||||
const handleToggleAreaActive = async (area: any) => {
|
||||
const askDeleteArea = (area: any) => {
|
||||
areaPendingDelete.value = area
|
||||
}
|
||||
|
||||
const closeDeleteAreaModal = () => {
|
||||
if (deletingAreaId.value) return
|
||||
areaPendingDelete.value = null
|
||||
}
|
||||
|
||||
const handleDeleteArea = async () => {
|
||||
if (!areaPendingDelete.value) return
|
||||
|
||||
const area = areaPendingDelete.value
|
||||
|
||||
deletingAreaId.value = area.id
|
||||
actionError.value = ''
|
||||
|
||||
try {
|
||||
const res = await updateArea(area.id, { active: !area.active })
|
||||
const res = await deleteArea(area.id)
|
||||
if (res.ok) {
|
||||
if (editingAreaId.value === area.id) {
|
||||
closeCreateModal()
|
||||
}
|
||||
await refresh()
|
||||
areaPendingDelete.value = null
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Failed to update area status', err)
|
||||
alert('Errore durante l\'aggiornamento dello stato area.')
|
||||
} catch (err: any) {
|
||||
console.error('Failed to delete area', err)
|
||||
actionError.value = err?.data?.message || 'Errore durante eliminazione area.'
|
||||
} finally {
|
||||
deletingAreaId.value = null
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -255,10 +284,14 @@ const handleToggleAreaActive = async (area: any) => {
|
||||
<div class="spinner-border text-primary" role="status"></div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="!areasRes?.areas || areasRes.areas.length === 0" class="alert alert-info">
|
||||
<div v-else-if="areas.length === 0" class="alert alert-info">
|
||||
Nessuna area configurata.
|
||||
</div>
|
||||
|
||||
<div v-if="actionError" class="alert alert-danger">
|
||||
{{ actionError }}
|
||||
</div>
|
||||
|
||||
<div v-else class="table-responsive">
|
||||
<table class="table table-hover align-middle bg-white shadow-sm rounded">
|
||||
<thead class="table-light">
|
||||
@@ -266,20 +299,15 @@ const handleToggleAreaActive = async (area: any) => {
|
||||
<th>ID</th>
|
||||
<th>Nome</th>
|
||||
<th>Descrizione</th>
|
||||
<th>Stato</th>
|
||||
<th>GeoJSON</th>
|
||||
<th class="text-end">Azioni</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="area in areasRes.areas" :key="area.id">
|
||||
<tr v-for="area in areas" :key="area.id">
|
||||
<td>{{ area.id }}</td>
|
||||
<td><strong>{{ area.name }}</strong></td>
|
||||
<td>{{ area.description || '-' }}</td>
|
||||
<td>
|
||||
<span v-if="area.active" class="badge bg-success">Attiva</span>
|
||||
<span v-else class="badge bg-secondary">Inattiva</span>
|
||||
</td>
|
||||
<td>
|
||||
<span v-if="area.boundary_geojson" class="badge border border-primary text-primary">Configurato</span>
|
||||
<span v-else class="badge border border-danger text-danger">Mancante</span>
|
||||
@@ -289,11 +317,12 @@ const handleToggleAreaActive = async (area: any) => {
|
||||
Modifica
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-sm"
|
||||
:class="area.active ? 'btn-outline-secondary' : 'btn-outline-success'"
|
||||
@click="handleToggleAreaActive(area)"
|
||||
class="btn btn-sm btn-outline-danger ms-2"
|
||||
:disabled="deletingAreaId === area.id"
|
||||
@click="askDeleteArea(area)"
|
||||
>
|
||||
{{ area.active ? 'Disattiva' : 'Attiva' }}
|
||||
<span v-if="deletingAreaId === area.id" class="spinner-border spinner-border-sm me-1"></span>
|
||||
Elimina
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -360,6 +389,17 @@ const handleToggleAreaActive = async (area: any) => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ConfirmModal
|
||||
:open="areaPendingDelete !== null"
|
||||
title="Elimina area"
|
||||
:message="areaPendingDelete ? `Vuoi eliminare area \\\"${areaPendingDelete.name}\\\"? Operazione irreversibile.` : ''"
|
||||
confirm-label="Elimina area"
|
||||
confirm-class="btn-danger"
|
||||
:pending="deletingAreaId !== null"
|
||||
@cancel="closeDeleteAreaModal"
|
||||
@confirm="handleDeleteArea"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user