Skip to main content

Descripción

useReportes es un composable de Vue que gestiona la obtención, agrupación y conteo de reportes ciudadanos desde Supabase. Proporciona funcionalidad para trabajar con reportes de usuarios, organizarlos por estado y obtener métricas.

Importación

import { useReportes } from '@/composables/useReportes'

Uso Básico

import { useReportes } from '@/composables/useReportes'

const { 
  reportes, 
  loading, 
  error, 
  obtenerReportesUsuario 
} = useReportes()

const cargarReportes = async () => {
  const usuarioId = 'uuid-del-usuario'
  await obtenerReportesUsuario(usuarioId)
  
  console.log('Reportes cargados:', reportes.value.length)
}

API

Valores Retornados

reportes
Ref<Reporte[]>
Array reactivo con los reportes obtenidos. Se actualiza automáticamente al llamar obtenerReportesUsuario().Tipo Reporte basado en Database['public']['Tables']['reportes']['Row']
loading
Ref<boolean>
Indica si hay una operación de carga en progreso. Útil para mostrar indicadores de carga en la UI.
error
Ref<string | null>
Contiene el mensaje de error si ocurre un problema al obtener los reportes. Es null cuando no hay errores.
obtenerReportesUsuario
(usuarioId: string) => Promise<Reporte[]>
Obtiene todos los reportes de un usuario específico desde Supabase, ordenados por fecha de creación (más recientes primero).Parámetros:
  • usuarioId (string) - UUID del usuario cuyos reportes se desean obtener
Retorna: Promise<Reporte[]> - Array de reportes del usuario (vacío si hay error)Efectos secundarios:
  • Actualiza reportes.value con los datos obtenidos
  • Actualiza loading.value durante la operación
  • Actualiza error.value si ocurre un error
agruparPorEstado
(reportesArray: Reporte[]) => Record<string, Reporte[]>
Agrupa un array de reportes por su estado.Parámetros:
  • reportesArray (Reporte[]) - Array de reportes a agrupar
Retorna: Record<string, Reporte[]> - Objeto con los reportes agrupados por estado:
  • pendiente - Reportes en estado inicial
  • en_revision - Reportes siendo evaluados
  • aceptado - Reportes aceptados
  • en_proceso - Reportes en resolución
  • resuelto - Reportes completados
  • rechazado - Reportes rechazados
  • duplicado - Reportes duplicados
contarPorEstado
(reportesArray: Reporte[]) => Record<string, number>
Cuenta el número de reportes en cada estado.Parámetros:
  • reportesArray (Reporte[]) - Array de reportes a contar
Retorna: Record<string, number> - Objeto con el conteo por estado:
  • pendiente - Número de reportes pendientes
  • en_revision - Número de reportes en revisión
  • aceptado - Número de reportes aceptados
  • en_proceso - Número de reportes en proceso
  • resuelto - Número de reportes resueltos
  • rechazado - Número de reportes rechazados
  • duplicado - Número de reportes duplicados

Tipo Reporte

El tipo Reporte corresponde a ReportesRow de la base de datos:
interface Reporte {
  id: string                        // UUID del reporte
  usuario_id: string                // UUID del usuario que creó el reporte
  categoria: ReporteCategoria       // Categoría del problema
  descripcion: string               // Descripción detallada
  ubicacion_parroquia: string       // Parroquia donde ocurre
  ubicacion_barrio: string          // Barrio específico
  ubicacion_direccion: string       // Dirección exacta
  ubicacion_lat: number | null      // Latitud (opcional)
  ubicacion_lng: number | null      // Longitud (opcional)
  estado: ReporteEstado             // Estado actual
  prioridad: ReportePrioridad       // Nivel de prioridad
  imagen_url: string | null         // URL de imagen adjunta
  respuesta_admin: string | null    // Respuesta del administrador
  fecha_resolucion: string | null   // Timestamp de resolución
  created_at: string | null         // Timestamp de creación
  updated_at: string | null         // Timestamp de actualización
}

type ReporteCategoria = 
  | 'alumbrado' | 'baches' | 'limpieza' | 'agua' 
  | 'alcantarillado' | 'parques' | 'señalizacion' 
  | 'seguridad' | 'ruido' | 'otro'

type ReporteEstado = 
  | 'pendiente' | 'en_revision' | 'en_proceso' 
  | 'resuelto' | 'rechazado'

type ReportePrioridad = 
  | 'baja' | 'media' | 'alta' | 'urgente'

Ejemplo Completo

<script setup lang="ts">
import { useReportes } from '@/composables/useReportes'
import { computed, onMounted } from 'vue'

const { 
  reportes, 
  loading, 
  error,
  obtenerReportesUsuario,
  contarPorEstado,
  agruparPorEstado
} = useReportes()

const usuarioId = 'uuid-del-usuario-actual'

// Cargar reportes al montar
onMounted(async () => {
  await obtenerReportesUsuario(usuarioId)
})

// Obtener estadísticas
const estadisticas = computed(() => {
  return contarPorEstado(reportes.value)
})

// Agrupar reportes
const reportesAgrupados = computed(() => {
  return agruparPorEstado(reportes.value)
})

// Reportes activos (no resueltos ni rechazados)
const reportesActivos = computed(() => {
  return reportes.value.filter(
    r => !['resuelto', 'rechazado'].includes(r.estado)
  )
})
</script>

<template>
  <div>
    <div v-if="loading">
      <p>Cargando reportes...</p>
    </div>
    
    <div v-else-if="error">
      <p class="text-red-600">Error: {{ error }}</p>
    </div>
    
    <div v-else>
      <!-- Estadísticas -->
      <div class="grid grid-cols-3 gap-4">
        <div>
          <h3>Pendientes</h3>
          <p>{{ estadisticas.pendiente }}</p>
        </div>
        <div>
          <h3>En Proceso</h3>
          <p>{{ estadisticas.en_proceso }}</p>
        </div>
        <div>
          <h3>Resueltos</h3>
          <p>{{ estadisticas.resuelto }}</p>
        </div>
      </div>

      <!-- Lista de reportes activos -->
      <div class="mt-6">
        <h2>Reportes Activos ({{ reportesActivos.length }})</h2>
        <div v-for="reporte in reportesActivos" :key="reporte.id">
          <div class="border p-4 rounded">
            <h3>{{ reporte.categoria }}</h3>
            <p>{{ reporte.descripcion }}</p>
            <span :class="getPrioridadColor(reporte.prioridad)">
              {{ reporte.prioridad }}
            </span>
            <span>Estado: {{ reporte.estado }}</span>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

Notas

  • Los reportes se ordenan por fecha de creación descendente (más recientes primero)
  • La función obtenerReportesUsuario actualiza automáticamente el estado reactivo reportes
  • El estado loading es útil para mostrar spinners durante la carga
  • El estado error contiene mensajes descriptivos en caso de fallo
  • Las funciones agruparPorEstado y contarPorEstado son puras y pueden usarse con cualquier array de reportes
  • Los estados disponibles están definidos en el tipo ReporteEstado de la base de datos

Build docs developers (and LLMs) love