- Create report creation page with step-by-step media uploads and categories loading - Create report details view page with history events log and messaging section - Implement MessageComposer and MessageList components for chat workflow - Implement MediaUploader with drag-and-drop support, file type, and size validation - Implement Pagination component with dynamic buttons and ellipsis support - Implement user profile settings summary page and notifications listing page
260 lines
8.9 KiB
Vue
260 lines
8.9 KiB
Vue
<script setup lang="ts">
|
|
definePageMeta({
|
|
middleware: 'auth',
|
|
})
|
|
|
|
useHead({ title: 'Il Mio Profilo - Visione' })
|
|
|
|
const { user, fetchRewards } = useAuth()
|
|
|
|
// Fetch rewards/punti
|
|
const page = ref(1)
|
|
const perPage = ref(10)
|
|
|
|
const { data: rewardsData } = await useAsyncData(() =>
|
|
fetchRewards({ page: page.value, per_page: perPage.value })
|
|
)
|
|
|
|
const rewards = computed(() => (rewardsData.value as any)?.reward_events || [])
|
|
const totalPoints = computed(() => (rewardsData.value as any)?.points || 0)
|
|
const totalRewards = computed(() => rewards.value.length)
|
|
|
|
const handlePageChange = (newPage: number) => {
|
|
page.value = newPage
|
|
}
|
|
|
|
const formatDate = (dateString: string): string => {
|
|
return new Date(dateString).toLocaleDateString('it-IT', {
|
|
day: '2-digit',
|
|
month: '2-digit',
|
|
year: 'numeric',
|
|
})
|
|
}
|
|
|
|
const handleLogout = () => {
|
|
useAuth().logout()
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<!-- HERO -->
|
|
<div class="bg-light border-bottom py-4 mb-5">
|
|
<div class="container">
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<h1 class="h3 font-weight-bold mb-3">Il Mio Profilo</h1>
|
|
<p class="text-muted">Gestisci i tuoi dati, visualizza i tuoi punti e la cronologia delle segnalazioni</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- CONTENUTO -->
|
|
<div class="container mb-5">
|
|
<div class="row">
|
|
|
|
<!-- SINISTRA: Profilo -->
|
|
<div class="col-12 col-lg-8">
|
|
|
|
<!-- DATI PERSONALI -->
|
|
<div class="card card-bg mb-4">
|
|
<div class="card-body">
|
|
<div class="d-flex align-items-center justify-content-between mb-4">
|
|
<h5 class="card-title font-weight-bold mb-0">
|
|
<BIIcon name="it-user" size="sm" color="primary" class="me-2" />
|
|
Dati Personali
|
|
</h5>
|
|
<NuxtLink to="/settings/profile" class="btn btn-sm btn-outline-primary">
|
|
<BIIcon name="it-pencil" size="xs" class="me-1" />
|
|
Modifica
|
|
</NuxtLink>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6 mb-3">
|
|
<small class="text-muted d-block">Nome</small>
|
|
<strong>{{ user?.first_name }}</strong>
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<small class="text-muted d-block">Cognome</small>
|
|
<strong>{{ user?.last_name }}</strong>
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<small class="text-muted d-block">Email</small>
|
|
<strong>{{ user?.email }}</strong>
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<small class="text-muted d-block">Codice Fiscale</small>
|
|
<strong>{{ user?.fiscal_code }}</strong>
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<small class="text-muted d-block">Telefono</small>
|
|
<strong>{{ user?.phone || 'Non fornito' }}</strong>
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<small class="text-muted d-block">Ruolo</small>
|
|
<span class="badge bg-info">{{ user?.role }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- PUNTI CITTADINO -->
|
|
<div class="card card-bg card-highlight mb-4">
|
|
<div class="card-body">
|
|
<h5 class="card-title font-weight-bold mb-4">
|
|
<BIIcon name="it-star" size="sm" color="warning" class="me-2" />
|
|
I Tuoi Punti Cittadino
|
|
</h5>
|
|
|
|
<div class="text-center p-4 bg-light rounded mb-4">
|
|
<div class="display-3 font-weight-bold text-primary">{{ totalPoints }}</div>
|
|
<small class="text-muted">Segnalazioni risolte completate con successo</small>
|
|
</div>
|
|
|
|
<div class="alert alert-info" role="alert">
|
|
<small>
|
|
<strong>Come guadagni punti?</strong><br>
|
|
Ricevi 1 punto per ogni segnalazione che risolviamo. Quando raggiungi determinati traguardi, potrai sbloccare riconoscimenti speciali!
|
|
</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- CRONOLOGIA PUNTI -->
|
|
<div class="card card-bg">
|
|
<div class="card-body">
|
|
<h5 class="card-title font-weight-bold mb-4">
|
|
<BIIcon name="it-history" size="sm" color="primary" class="me-2" />
|
|
Cronologia Punti (ultimi {{ rewards.length }})
|
|
</h5>
|
|
|
|
<div v-if="rewards.length === 0" class="alert alert-info" role="alert">
|
|
Non hai ancora accumulato punti. Crea la tua prima segnalazione!
|
|
</div>
|
|
|
|
<div v-else class="table-responsive">
|
|
<table class="table table-hover mb-0">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th scope="col" class="small">Data</th>
|
|
<th scope="col" class="small">Segnalazione</th>
|
|
<th scope="col" class="text-center small">Punti</th>
|
|
<th scope="col" class="small">Motivo</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr v-for="reward in rewards" :key="reward.id">
|
|
<td class="small">
|
|
<small class="text-muted">{{ formatDate(reward.created_at) }}</small>
|
|
</td>
|
|
<td class="small">
|
|
<NuxtLink :to="`/reports/${reward.report_id}`" class="text-decoration-none">
|
|
#{{ reward.report_id }}
|
|
</NuxtLink>
|
|
</td>
|
|
<td class="text-center">
|
|
<span class="badge bg-success">+{{ reward.points }}</span>
|
|
</td>
|
|
<td class="small">{{ reward.reason }}</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<!-- PAGINATION -->
|
|
<Pagination
|
|
v-if="rewards.length > 0"
|
|
:current-page="page"
|
|
:per-page="perPage"
|
|
:total-items="totalRewards"
|
|
@page-change="handlePageChange"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- DESTRA: Azioni rapide -->
|
|
<div class="col-12 col-lg-4">
|
|
|
|
<!-- NUOVA SEGNALAZIONE -->
|
|
<div class="card card-bg card-highlight mb-4">
|
|
<div class="card-body text-center">
|
|
<BIIcon name="it-plus-circle" size="xl" color="primary" class="mb-3" />
|
|
<h6 class="font-weight-bold mb-3">Crea una nuova segnalazione</h6>
|
|
<p class="small text-muted mb-3">Aiutaci a migliorare il tuo quartiere</p>
|
|
<NuxtLink to="/reports/create" class="btn btn-primary w-100">
|
|
Segnala ora
|
|
</NuxtLink>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- LE MIE SEGNALAZIONI -->
|
|
<div class="card card-bg mb-4">
|
|
<div class="card-body">
|
|
<h6 class="card-title font-weight-bold mb-3">
|
|
<BIIcon name="it-list" size="sm" color="primary" class="me-2" />
|
|
Le Mie Segnalazioni
|
|
</h6>
|
|
<NuxtLink to="/dashboard" class="btn btn-outline-primary w-100 btn-sm">
|
|
Vai alla Dashboard
|
|
</NuxtLink>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- NOTIFICHE -->
|
|
<div class="card card-bg mb-4">
|
|
<div class="card-body">
|
|
<h6 class="card-title font-weight-bold mb-3">
|
|
<BIIcon name="it-bell" size="sm" color="primary" class="me-2" />
|
|
Centro Notifiche
|
|
</h6>
|
|
<NuxtLink to="/notifications" class="btn btn-outline-primary w-100 btn-sm">
|
|
Visualizza notifiche
|
|
</NuxtLink>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- IMPOSTAZIONI & LOGOUT -->
|
|
<div class="card card-bg">
|
|
<div class="card-body">
|
|
<h6 class="card-title font-weight-bold mb-3">
|
|
<BIIcon name="it-settings" size="sm" color="primary" class="me-2" />
|
|
Account
|
|
</h6>
|
|
<NuxtLink to="/settings/password" class="btn btn-outline-secondary w-100 btn-sm mb-2">
|
|
Cambia Password
|
|
</NuxtLink>
|
|
<button type="button" class="btn btn-outline-danger w-100 btn-sm" @click="handleLogout">
|
|
Logout
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.card-highlight {
|
|
border-color: #ffc107;
|
|
}
|
|
|
|
.display-3 {
|
|
font-size: 3.5rem;
|
|
line-height: 1;
|
|
}
|
|
|
|
.table-hover tbody tr:hover {
|
|
background-color: rgba(0, 111, 157, 0.05);
|
|
}
|
|
</style>
|
|
|
|
|