Skip to main content

Overview

The useReportesStore manages citizen reports (reportes) with support for filtering, image uploads, real-time subscriptions, and status tracking. It handles the full lifecycle of community reports from creation to resolution.

State Properties

reportes
Reporte[]
Array of reports
reporteActual
Reporte | null
Currently selected/viewed report
loading
boolean
Loading state for async operations
error
string | null
Error message from last failed operation

Actions

fetchReportes

Fetches reports with optional filters.
const result = await reportesStore.fetchReportes(filtros)
filtros
object
Optional filters for reports
return
Promise<{ success: boolean; data?: Reporte[]; error?: string }>
Result object with reports array
Example:
// Get user's pending reports
await reportesStore.fetchReportes({
  usuario_id: authStore.user.id,
  estado: 'pendiente'
})

fetchReporte

Fetches a single report by ID.
const result = await reportesStore.fetchReporte(id)
id
string
required
Report ID
return
Promise<{ success: boolean; data?: Reporte; error?: string }>
Result object with report data

crearReporte

Creates a new citizen report.
const result = await reportesStore.crearReporte(reporte)
reporte
Omit<InsertReporte, 'usuario_id'>
required
Report data (usuario_id is added automatically)
return
Promise<{ success: boolean; data?: Reporte; error?: string }>
Result object with created report data
Behavior:
  • Requires authenticated user
  • Adds usuario_id automatically from auth store
  • Prepends new report to local reportes array
  • Logs detailed information for debugging

actualizarReporte

Updates an existing report (typically used by admins).
const result = await reportesStore.actualizarReporte(id, updates)
id
string
required
Report ID to update
updates
Omit<UpdateReporte, 'id' | 'usuario_id'>
required
Fields to update
return
Promise<{ success: boolean; data?: Reporte; error?: string }>
Result object with updated report data
Behavior:
  • Updates report in local reportes array if present
  • Updates reporteActual if it’s the currently viewed report

eliminarReporte

Deletes a report.
const result = await reportesStore.eliminarReporte(id)
id
string
required
Report ID to delete
return
Promise<{ success: boolean; error?: string }>
Result object indicating success or failure

subirImagen

Uploads an image to Supabase storage for a report.
const result = await reportesStore.subirImagen(file, reporteId)
file
File
required
Image file to upload
reporteId
string
required
Report ID (used in filename)
return
Promise<{ success: boolean; url?: string; error?: string }>
Result object with public URL of uploaded image
Behavior:
  • Generates unique filename: {reporteId}-{timestamp}.{ext}
  • Uploads to imagenes/reportes/ bucket
  • Returns public URL for use in report imagen_url field

subscribeToReportes

Subscribes to real-time updates for reports.
const subscription = reportesStore.subscribeToReportes()

// Later, to unsubscribe:
subscription.unsubscribe()
return
RealtimeChannel
Supabase realtime channel subscription
Features:
  • Automatically filters updates based on user role:
    • Citizens: Only see updates to their own reports
    • Admins: See all report updates
  • Handles INSERT, UPDATE, and DELETE events
  • Updates local state automatically
  • Logs changes to console

Usage Examples

<script setup>
import { useReportesStore } from '@/stores/reportes.store'
import { ref } from 'vue'

const reportesStore = useReportesStore()
const imageFile = ref<File | null>(null)

async function enviarReporte() {
  let imageUrl = null
  
  // First, upload image if provided
  if (imageFile.value) {
    const uploadResult = await reportesStore.subirImagen(
      imageFile.value,
      'temp-' + Date.now() // Temporary ID
    )
    
    if (uploadResult.success) {
      imageUrl = uploadResult.url
    }
  }
  
  // Then create report
  const result = await reportesStore.crearReporte({
    titulo: 'Bache en la vía principal',
    descripcion: 'Hay un bache grande que necesita reparación',
    categoria: 'infraestructura',
    ubicacion: 'Av. Principal, frente al parque',
    latitud: -0.95,
    longitud: -80.73,
    imagen_url: imageUrl,
    estado: 'pendiente'
  })
  
  if (result.success) {
    console.log('Reporte creado:', result.data?.id)
  }
}
</script>

Report Status Flow

Typical Report Lifecycle:
  1. pendiente (Pending): Initial state when citizen creates report
  2. en_proceso (In Progress): Admin has acknowledged and is working on it
  3. resuelto (Resolved): Issue has been fixed
  4. rechazado (Rejected): Report was invalid or duplicate

Real-time Updates

The subscribeToReportes() action creates a persistent connection. Always unsubscribe when the component unmounts to prevent memory leaks.
Real-time filtering by user role:
  • Citizens automatically see only updates to their own reports
  • Admins see all report changes across the system

Image Upload

Upload images BEFORE creating the report to get the URL, then include it in the report data. The filename includes the report ID and timestamp for uniqueness.

Notes

All reports are ordered by created_at in descending order (newest first) by default.

Build docs developers (and LLMs) love