feat: more authentication failchecks
This commit is contained in:
+36
-11
@@ -21,6 +21,7 @@ const formData = reactive({
|
|||||||
})
|
})
|
||||||
const jsonError = ref('')
|
const jsonError = ref('')
|
||||||
const actionError = ref('')
|
const actionError = ref('')
|
||||||
|
const modalError = ref('')
|
||||||
const deletingAreaId = ref<number | null>(null)
|
const deletingAreaId = ref<number | null>(null)
|
||||||
const areaPendingDelete = ref<any | null>(null)
|
const areaPendingDelete = ref<any | null>(null)
|
||||||
|
|
||||||
@@ -121,13 +122,15 @@ const renderExistingAreasInModal = (L: any, currentMap: any) => {
|
|||||||
},
|
},
|
||||||
interactive: false
|
interactive: false
|
||||||
}).addTo(currentMap)
|
}).addTo(currentMap)
|
||||||
} catch(e) {}
|
} catch (e) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const openCreateModal = () => {
|
const openCreateModal = () => {
|
||||||
actionError.value = ''
|
actionError.value = ''
|
||||||
|
modalError.value = ''
|
||||||
editingAreaId.value = null
|
editingAreaId.value = null
|
||||||
formData.name = ''
|
formData.name = ''
|
||||||
formData.description = ''
|
formData.description = ''
|
||||||
@@ -171,6 +174,7 @@ const openCreateModal = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
jsonError.value = ''
|
jsonError.value = ''
|
||||||
|
modalError.value = ''
|
||||||
mapPoints.value.push([e.latlng.lat, e.latlng.lng])
|
mapPoints.value.push([e.latlng.lat, e.latlng.lng])
|
||||||
polygon.setLatLngs(mapPoints.value)
|
polygon.setLatLngs(mapPoints.value)
|
||||||
updateGeojson()
|
updateGeojson()
|
||||||
@@ -197,6 +201,7 @@ const loadPolygonFromGeoJson = (boundaryGeojson: any) => {
|
|||||||
|
|
||||||
const openEditModal = (area: any) => {
|
const openEditModal = (area: any) => {
|
||||||
actionError.value = ''
|
actionError.value = ''
|
||||||
|
modalError.value = ''
|
||||||
editingAreaId.value = area.id
|
editingAreaId.value = area.id
|
||||||
formData.name = area.name || ''
|
formData.name = area.name || ''
|
||||||
formData.description = area.description || ''
|
formData.description = area.description || ''
|
||||||
@@ -250,6 +255,7 @@ const openEditModal = (area: any) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
jsonError.value = ''
|
jsonError.value = ''
|
||||||
|
modalError.value = ''
|
||||||
mapPoints.value.push([e.latlng.lat, e.latlng.lng])
|
mapPoints.value.push([e.latlng.lat, e.latlng.lng])
|
||||||
polygon.setLatLngs(mapPoints.value)
|
polygon.setLatLngs(mapPoints.value)
|
||||||
updateGeojson()
|
updateGeojson()
|
||||||
@@ -263,6 +269,7 @@ const clearMap = () => {
|
|||||||
polygon.setLatLngs([])
|
polygon.setLatLngs([])
|
||||||
}
|
}
|
||||||
formData.geojson = ''
|
formData.geojson = ''
|
||||||
|
modalError.value = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateGeojson = () => {
|
const updateGeojson = () => {
|
||||||
@@ -270,7 +277,7 @@ const updateGeojson = () => {
|
|||||||
formData.geojson = ''
|
formData.geojson = ''
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const coords = mapPoints.value.map(p => [p[1], p[0]] as [number, number]) // Lng, Lat
|
const coords = mapPoints.value.map(p => [p[1], p[0]] as [number, number])
|
||||||
if (coords[0]) {
|
if (coords[0]) {
|
||||||
coords.push([...coords[0]])
|
coords.push([...coords[0]])
|
||||||
}
|
}
|
||||||
@@ -297,6 +304,7 @@ onBeforeUnmount(() => {
|
|||||||
|
|
||||||
const handleCreate = async () => {
|
const handleCreate = async () => {
|
||||||
jsonError.value = ''
|
jsonError.value = ''
|
||||||
|
modalError.value = ''
|
||||||
let parsedGeojson = null
|
let parsedGeojson = null
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -331,9 +339,16 @@ const handleCreate = async () => {
|
|||||||
closeCreateModal()
|
closeCreateModal()
|
||||||
actionError.value = ''
|
actionError.value = ''
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err: any) {
|
||||||
console.error('Failed to save area', err)
|
console.error('Failed to save area', err)
|
||||||
actionError.value = 'Errore durante il salvataggio dell\'area.'
|
|
||||||
|
const backendError = err?.data?.error || err?.response?.data?.error || err?.response?._data?.error;
|
||||||
|
|
||||||
|
if (backendError === 'area_outside_allowed_boundary') {
|
||||||
|
modalError.value = "Attenzione: l'area disegnata esce dai confini consentiti per il Comune di Bari.";
|
||||||
|
} else {
|
||||||
|
modalError.value = err?.data?.message || err?.message || "Errore durante il salvataggio dell'area.";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,7 +394,7 @@ const handleDeleteArea = async () => {
|
|||||||
<div>
|
<div>
|
||||||
<NuxtLink to="/dashboard" class="btn btn-outline-secondary btn-sm me-2">Torna al pannello admin</NuxtLink>
|
<NuxtLink to="/dashboard" class="btn btn-outline-secondary btn-sm me-2">Torna al pannello admin</NuxtLink>
|
||||||
<button class="btn btn-primary btn-sm" @click="openCreateModal">
|
<button class="btn btn-primary btn-sm" @click="openCreateModal">
|
||||||
<BIIcon name="it-plus" size="xs" class="me-1" />
|
<BIIcon class="me-1" name="it-plus" size="xs"/>
|
||||||
Nuova Area
|
Nuova Area
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -441,7 +456,8 @@ const handleDeleteArea = async () => {
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div v-if="isCreating" class="modal-backdrop fade show d-block" style="background: rgba(0,0,0,0.5); z-index: 1040;"></div>
|
<div v-if="isCreating" class="modal-backdrop fade show d-block"
|
||||||
|
style="background: rgba(0,0,0,0.5); z-index: 1040;"></div>
|
||||||
<div v-if="isCreating" class="modal fade show d-block" tabindex="-1" style="z-index: 1050;">
|
<div v-if="isCreating" class="modal fade show d-block" tabindex="-1" style="z-index: 1050;">
|
||||||
<div class="modal-dialog modal-xl modal-dialog-centered modal-dialog-scrollable">
|
<div class="modal-dialog modal-xl modal-dialog-centered modal-dialog-scrollable">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
@@ -450,12 +466,19 @@ const handleDeleteArea = async () => {
|
|||||||
<button type="button" class="btn-close" @click="closeCreateModal"></button>
|
<button type="button" class="btn-close" @click="closeCreateModal"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
|
<!-- ALERT ERRORE DEL BACKEND -->
|
||||||
|
<div v-if="modalError" class="alert alert-danger mb-4 d-flex align-items-center" role="alert">
|
||||||
|
<strong>Errore:</strong> {{ modalError }}
|
||||||
|
</div>
|
||||||
|
|
||||||
<form @submit.prevent="handleCreate">
|
<form @submit.prevent="handleCreate">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-5">
|
<div class="col-md-5">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label">Nome Area</label>
|
<label class="form-label">Nome Area</label>
|
||||||
<input type="text" class="form-control" v-model="formData.name" required placeholder="Es. Centro Storico" />
|
<input v-model="formData.name" class="form-control" placeholder="Es. Centro Storico" required
|
||||||
|
type="text"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label">Descrizione (opzionale)</label>
|
<label class="form-label">Descrizione (opzionale)</label>
|
||||||
@@ -483,7 +506,8 @@ const handleDeleteArea = async () => {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="alert alert-light border small mb-2 p-2">
|
<div class="alert alert-light border small mb-2 p-2">
|
||||||
Clicca sulla mappa per aggiungere vertici al poligono. Sono necessari almeno 3 punti. Sono ammessi solo punti nel Comune di Bari.
|
Clicca sulla mappa per aggiungere vertici al poligono. Sono necessari almeno 3 punti. Sono ammessi
|
||||||
|
solo punti nel Comune di Bari.
|
||||||
</div>
|
</div>
|
||||||
<div id="areaMap" class="rounded border" style="height: 400px; width: 100%; z-index: 1;"></div>
|
<div id="areaMap" class="rounded border" style="height: 400px; width: 100%; z-index: 1;"></div>
|
||||||
</div>
|
</div>
|
||||||
@@ -492,7 +516,8 @@ const handleDeleteArea = async () => {
|
|||||||
</div>
|
</div>
|
||||||
<div class="modal-footer d-flex justify-content-end gap-2">
|
<div class="modal-footer d-flex justify-content-end gap-2">
|
||||||
<button type="button" class="btn btn-outline-secondary" @click="closeCreateModal">Annulla</button>
|
<button type="button" class="btn btn-outline-secondary" @click="closeCreateModal">Annulla</button>
|
||||||
<button type="button" class="btn btn-primary" :disabled="!formData.name || !formData.geojson" @click="handleCreate">
|
<button :disabled="!formData.name || !formData.geojson" class="btn btn-primary" type="button"
|
||||||
|
@click="handleCreate">
|
||||||
{{ submitLabel }}
|
{{ submitLabel }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -519,6 +544,6 @@ const handleDeleteArea = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.modal-dialog {
|
.modal-dialog {
|
||||||
margin-block: 0!important;
|
margin-block: 0 !important;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
+3
-1
@@ -3,6 +3,8 @@ import BIIcon from "~/components/BIIcon.vue";
|
|||||||
|
|
||||||
const { getOpenDataReports } = usePublic()
|
const { getOpenDataReports } = usePublic()
|
||||||
|
|
||||||
|
const { user } = useAuth();
|
||||||
|
|
||||||
const stats = {
|
const stats = {
|
||||||
total_reports: 14523,
|
total_reports: 14523,
|
||||||
resolved_reports: 13890,
|
resolved_reports: 13890,
|
||||||
@@ -38,7 +40,7 @@ const getStatusBadge = (status: string) => {
|
|||||||
e monitora l'intervento in totale trasparenza.
|
e monitora l'intervento in totale trasparenza.
|
||||||
</p>
|
</p>
|
||||||
<div class="it-btn-container d-flex justify-content-center gap-3">
|
<div class="it-btn-container d-flex justify-content-center gap-3">
|
||||||
<NuxtLink class="btn btn-primary" to="/auth/login">
|
<NuxtLink v-if="isCitizen(user.value?.role)" class="btn btn-primary" to="/auth/login">
|
||||||
Fai una segnalazione
|
Fai una segnalazione
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
<NuxtLink class="btn btn-outline-primary" to="/open-data">
|
<NuxtLink class="btn btn-outline-primary" to="/open-data">
|
||||||
|
|||||||
@@ -122,7 +122,6 @@ const initMap = async () => {
|
|||||||
watch(currentView, async (view) => {
|
watch(currentView, async (view) => {
|
||||||
if (view !== 'map') return
|
if (view !== 'map') return
|
||||||
await nextTick()
|
await nextTick()
|
||||||
// Inizializza la mappa se non esiste, altrimenti aggiornane solo dimensioni e dati
|
|
||||||
if (!map) {
|
if (!map) {
|
||||||
await initMap()
|
await initMap()
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -130,7 +130,8 @@ const formatDate = (dateString: string) =>
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h2 class="h6 card-title mb-3">Azioni account</h2>
|
<h2 class="h6 card-title mb-3">Azioni account</h2>
|
||||||
<div class="d-grid gap-2">
|
<div class="d-grid gap-2">
|
||||||
<NuxtLink to="/reports/new" class="btn btn-primary">Nuova segnalazione</NuxtLink>
|
<NuxtLink v-if="isCitizen(user?.role)" class="btn btn-primary" to="/reports/new">Nuova segnalazione
|
||||||
|
</NuxtLink>
|
||||||
<NuxtLink to="/notifications" class="btn btn-outline-primary">Notifiche</NuxtLink>
|
<NuxtLink to="/notifications" class="btn btn-outline-primary">Notifiche</NuxtLink>
|
||||||
<button type="button" class="btn btn-outline-danger" @click="logout">
|
<button type="button" class="btn btn-outline-danger" @click="logout">
|
||||||
Logout
|
Logout
|
||||||
|
|||||||
Reference in New Issue
Block a user