Compare commits
2
Commits
8e5f041527
...
5fc5457316
+19
-6
@@ -29,6 +29,16 @@ const prevPage = () => {
|
|||||||
if (currentPage.value > 1) currentPage.value--
|
if (currentPage.value > 1) currentPage.value--
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { data: mapOpenDataResponse, pending: mapPending } = useAsyncData(
|
||||||
|
'open-data-map-reports',
|
||||||
|
() => getOpenDataReports({ page: 1, per_page: 200 }),
|
||||||
|
{ lazy: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
const mapVisibleReports = computed(() =>
|
||||||
|
(mapOpenDataResponse.value?.reports || []).filter((report) => isWithinBariBounds(report.latitude, report.longitude))
|
||||||
|
)
|
||||||
|
|
||||||
const currentView = ref<'grid' | 'map'>('grid')
|
const currentView = ref<'grid' | 'map'>('grid')
|
||||||
const mapContainer = ref<HTMLElement | null>(null)
|
const mapContainer = ref<HTMLElement | null>(null)
|
||||||
let leaflet: typeof import('leaflet') | null = null
|
let leaflet: typeof import('leaflet') | null = null
|
||||||
@@ -66,12 +76,12 @@ const renderMapMarkers = async () => {
|
|||||||
|
|
||||||
clearMarkers()
|
clearMarkers()
|
||||||
|
|
||||||
if (visibleReports.value.length === 0) {
|
if (mapVisibleReports.value.length === 0) {
|
||||||
map.setView(BARI_CENTER, 12)
|
map.setView(BARI_CENTER, 12)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
visibleReports.value.forEach((report) => {
|
mapVisibleReports.value.forEach((report) => {
|
||||||
const marker = L.circleMarker([report.latitude, report.longitude], {
|
const marker = L.circleMarker([report.latitude, report.longitude], {
|
||||||
radius: 8,
|
radius: 8,
|
||||||
weight: 2,
|
weight: 2,
|
||||||
@@ -93,7 +103,7 @@ const renderMapMarkers = async () => {
|
|||||||
markers.push(marker)
|
markers.push(marker)
|
||||||
})
|
})
|
||||||
|
|
||||||
const fitBounds: LatLngBoundsExpression = visibleReports.value.map((report) => [report.latitude, report.longitude])
|
const fitBounds: LatLngBoundsExpression = mapVisibleReports.value.map((report) => [report.latitude, report.longitude])
|
||||||
map.fitBounds(fitBounds, { padding: [32, 32], maxZoom: 15 })
|
map.fitBounds(fitBounds, { padding: [32, 32], maxZoom: 15 })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,7 +140,7 @@ watch(currentView, async (view) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(visibleReports, async () => {
|
watch(mapVisibleReports, async () => {
|
||||||
if (currentView.value === 'map' && map) {
|
if (currentView.value === 'map' && map) {
|
||||||
await renderMapMarkers()
|
await renderMapMarkers()
|
||||||
}
|
}
|
||||||
@@ -266,7 +276,10 @@ onBeforeUnmount(() => {
|
|||||||
<div v-show="!pending && currentView === 'map'" class="map-view-wrapper">
|
<div v-show="!pending && currentView === 'map'" class="map-view-wrapper">
|
||||||
<div class="d-flex justify-content-between align-items-center flex-wrap gap-2 mb-3">
|
<div class="d-flex justify-content-between align-items-center flex-wrap gap-2 mb-3">
|
||||||
<p class="text-muted mb-0">Mappa pubblica delle segnalazioni nell'area di Bari.</p>
|
<p class="text-muted mb-0">Mappa pubblica delle segnalazioni nell'area di Bari.</p>
|
||||||
<span class="badge bg-light text-dark border">{{ visibleReports.length }} punti</span>
|
<span class="badge bg-light text-dark border">
|
||||||
|
<template v-if="mapPending">Caricamento...</template>
|
||||||
|
<template v-else>{{ mapVisibleReports.length }} punti</template>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<ClientOnly>
|
<ClientOnly>
|
||||||
<div ref="mapContainer" class="open-data-map rounded border"></div>
|
<div ref="mapContainer" class="open-data-map rounded border"></div>
|
||||||
@@ -305,4 +318,4 @@ onBeforeUnmount(() => {
|
|||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
min-width: 12rem;
|
min-width: 12rem;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -69,6 +69,12 @@ const handleSubmitFeedback = async () => {
|
|||||||
const isOwner = computed(() => report.value?.user_id === user.value?.id)
|
const isOwner = computed(() => report.value?.user_id === user.value?.id)
|
||||||
const canFeedback = computed(() => report.value?.status === 'RESOLVED')
|
const canFeedback = computed(() => report.value?.status === 'RESOLVED')
|
||||||
|
|
||||||
|
const canChat = computed(() => {
|
||||||
|
if (!report.value) return false
|
||||||
|
const closedStatuses = ['RESOLVED', 'CLOSED', 'REJECTED']
|
||||||
|
return !closedStatuses.includes(report.value.status)
|
||||||
|
})
|
||||||
|
|
||||||
const statusMeta: Record<string, { label: string; tone: string }> = {
|
const statusMeta: Record<string, { label: string; tone: string }> = {
|
||||||
OPEN: { label: 'Aperta', tone: 'info' },
|
OPEN: { label: 'Aperta', tone: 'info' },
|
||||||
UNDER_REVIEW: { label: 'In revisione', tone: 'warning' },
|
UNDER_REVIEW: { label: 'In revisione', tone: 'warning' },
|
||||||
@@ -210,7 +216,12 @@ const formatDate = (dateString: string): string => {
|
|||||||
|
|
||||||
<MessageList :messages="messages"/>
|
<MessageList :messages="messages"/>
|
||||||
|
|
||||||
<MessageComposer @send="handleSendMessage"/>
|
<MessageComposer v-if="canChat" @send="handleSendMessage"/>
|
||||||
|
<div v-else class="alert alert-secondary mt-3 mb-0 text-center small">
|
||||||
|
La chat è disabilitata poiché la segnalazione è in stato
|
||||||
|
<strong>{{ statusMeta[report.status]?.label || report.status }}</strong>.
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user