feat: implement dynamic dashboard routing with role-specific views

- Create unified dashboard page that renders dashboard view based on user role
- Implement CitizenDashboard with local filtering, pagination, and user rewards points visualization
- Implement OperatorDashboard with list of open/assigned reports and assignment actions
- Implement AdminDashboard with admin statistics overview card components and management links
This commit is contained in:
2026-06-12 19:04:19 +02:00 Unverified
parent 794f6e835a
commit 4c6367b328
4 changed files with 451 additions and 0 deletions
+80
View File
@@ -0,0 +1,80 @@
<script setup lang="ts">
definePageMeta({
middleware: 'auth'
})
const { user } = useAuth()
import CitizenDashboard from '~/components/dashboard/CitizenDashboard.vue'
import OperatorDashboard from '~/components/dashboard/OperatorDashboard.vue'
import AdminDashboard from '~/components/dashboard/AdminDashboard.vue'
// Normalizziamo in uppercase nel caso il backend risponda con 'citizen' o 'CITIZEN'
const currentDashboard = computed(() => {
const role = user.value?.role?.toUpperCase()
if (role === 'CITIZEN') return CitizenDashboard
if (role === 'OPERATOR') return OperatorDashboard
if (role === 'ADMIN') return AdminDashboard
return null
})
// Testi dinamici per l'Hero (la fascia blu in alto) in base al ruolo
const heroTitle = computed(() => {
const role = user.value?.role?.toUpperCase()
if (role === 'ADMIN') return 'Pannello di Amministrazione'
if (role === 'OPERATOR') return 'Gestione Operativa'
return 'Le Mie Segnalazioni' // Cittadino
})
const heroSubtitle = computed(() => {
const role = user.value?.role?.toUpperCase()
if (role === 'ADMIN') return 'Gestione del sistema, delle aree e moderazione utenti'
if (role === 'OPERATOR') return 'Prendi in carico e gestisci le segnalazioni in corso'
return 'Traccia lo stato di tutte le tue segnalazioni e comunica con gli operatori' // Cittadino
})
</script>
<template>
<div>
<div class="it-hero-wrapper it-primary">
<div class="container">
<div class="row">
<div class="col-12">
<div class="it-hero-text-wrapper p-4">
<h1 class="text-white font-weight-bold">{{ heroTitle }}</h1>
<p class="text-white mt-2 lead">
{{ heroSubtitle }}
</p>
</div>
</div>
</div>
</div>
</div>
<div class="container my-5">
<div class="row mb-4">
<div class="col-12">
<h4 class="mb-2 text-muted">
Benvenuto, <strong>{{ user?.first_name }} {{ user?.last_name }}</strong>.
</h4>
</div>
</div>
<!-- Qui viene montato CitizenDashboard.vue, OperatorDashboard.vue o AdminDashboard.vue -->
<component :is="currentDashboard" v-if="currentDashboard" />
<div v-else class="alert alert-warning" role="alert">
Caricamento pannello di controllo in corso...
</div>
</div>
</div>
</template>
<style scoped>
/* Il gradiente originale della pagina rotta */
.it-primary {
background: linear-gradient(135deg, #006f9d 0%, #003d5c 100%);
}
</style>