The Incidents App provides a comprehensive incident tracking system that allows guests to report issues and staff to manage and resolve them efficiently.
Overview
The incident tracking system manages the complete lifecycle of incidents from creation to resolution, with real-time status updates and role-based task assignment.
Incident Lifecycle
Incident Creation
Guests create incidents through the CreateIncidentForm component, providing:
Title : Brief description of the issue
Description : Detailed explanation
Priority : Low (baja), Medium (media), or High (alta)
Area : The responsible department
Task Assignment
Incidents appear in the area’s inbox as pending tasks. Staff members can accept tasks from the general inbox.
Progress Tracking
Once accepted, the incident moves through status stages:
pendiente (Pending)
recibida (Received)
en_progreso (In Progress)
resuelta (Resolved)
Resolution
Staff members resolve incidents by providing a resolution description and optional evidence photos.
Creating Incidents
The CreateIncidentForm component handles incident creation with form validation and area selection:
const handleSubmit = async () => {
if ( ! title . trim () || ! description . trim () || ! priority || ! areaId ) {
Alert . alert ( "Error" , "Completa todos los campos" );
return ;
}
const raw = await SecureStore . getItemAsync ( "guest_session" );
if ( ! raw ) throw new Error ( "No hay sesión de huésped" );
const guestSession = JSON . parse ( raw );
const { error } = await supabase . from ( "incidents" ). insert ({
title ,
description ,
priority ,
area_id: areaId ,
room_id: guestSession . room_id ,
});
if ( error ) throw error ;
Alert . alert ( "Listo" , "Incidencia enviada" );
};
Incidents are automatically linked to the guest’s room via the guest_session stored in secure storage.
Priority Levels
Incidents support three priority levels with visual indicators:
Low Priority Non-urgent issues that can be addressed during regular maintenance
Medium Priority Issues requiring attention within the same day
High Priority Urgent issues requiring immediate attention
const priorityOptions = [
{ value: "baja" , label: "Baja" , color: "#10B981" , bgColor: "#ECFDF5" },
{ value: "media" , label: "Media" , color: "#F59E0B" , bgColor: "#FEF3C7" },
{ value: "alta" , label: "Alta" , color: "#EF4444" , bgColor: "#FEE2E2" },
];
Viewing Incidents
Guest View
Guests can view their submitted incidents through the MyIncidentsView component:
const loadIncidents = async () => {
const raw = await SecureStore . getItemAsync ( "guest_session" );
const guestSession = JSON . parse ( raw );
const { data , error } = await supabase
. from ( "incidents" )
. select (
"id, title, description, priority, status, created_at, areas(name)"
)
. eq ( "room_id" , guestSession . room_id )
. order ( "created_at" , { ascending: false });
setIncidents (( data || []) as unknown as Incident []);
};
Staff View
Staff members see incidents in two views:
Shows incidents assigned to the logged-in employee: const { data , error } = await supabase
. from ( "incidents" )
. select (
"id, title, description, priority, status, created_at, areas(name)"
)
. eq ( "assigned_to" , user . id )
. order ( "created_at" , { ascending: false });
Shows all pending incidents for the employee’s area: EmpleadoBuzonIncidents.tsx
const { data , error } = await supabase
. from ( "incidents" )
. select (
"id, title, description, priority, status, created_at, areas(name), rooms(room_code)"
)
. eq ( "status" , "pendiente" )
. eq ( "area_id" , areaData . id )
. order ( "created_at" , { ascending: false });
Incident Card Component
The IncidentCard component displays incident information with visual status indicators:
const statusConfig : Record < string , { label : string ; color : string ; textColor : string }> = {
pendiente: { label: "Pendiente" , color: "#6b72801c" , textColor: "#6b7280da" },
recibida: { label: "Recibida" , color: "#FEF3C7" , textColor: "#F59E0B" },
en_progreso: {
label: "En Progreso" ,
color: "#3b83f61a" ,
textColor: "#3b83f6cd" ,
},
resuelta: { label: "Resuelta" , color: "#10b98119" , textColor: "#10b981c3" },
};
The card component is reusable across both guest and staff interfaces with different interaction behaviors.
Task Management
Accepting Tasks
Staff members can accept tasks from the general inbox:
const handleAcceptTask = async () => {
// Verify task is still pending
const { data : currentIncident } = await supabase
. from ( "incidents" )
. select ( "status" )
. eq ( "id" , id )
. single ();
if ( currentIncident . status !== "pendiente" ) {
Alert . alert (
"Tarea no disponible" ,
"Esta tarea ya fue aceptada por otro empleado del área."
);
return ;
}
// Accept the task
const { error } = await supabase
. from ( "incidents" )
. update ({
status: "recibida" ,
assigned_to: currentUserId ,
})
. eq ( "id" , id );
};
Updating Status
Once received, staff can update the status to “in progress” by tapping the status badge:
const handleStatusClick = async () => {
if ( incident ?. status !== "recibida" || ! isAssignedToMe ) return ;
const { error } = await supabase
. from ( "incidents" )
. update ({
status: "en_progreso" ,
updated_at: new Date (). toISOString (),
})
. eq ( "id" , id );
};
Rejecting Tasks
Staff can reject tasks to return them to the general inbox:
const handleRejectTask = async () => {
const { error } = await supabase
. from ( "incidents" )
. update ({
status: "pendiente" ,
assigned_to: null ,
})
. eq ( "id" , id );
};
Database Schema
The incidents table structure:
CREATE TABLE incidents (
id UUID PRIMARY KEY ,
title TEXT NOT NULL ,
description TEXT NOT NULL ,
priority TEXT CHECK ( priority IN ( 'baja' , 'media' , 'alta' )),
status TEXT CHECK ( status IN ( 'pendiente' , 'recibida' , 'en_progreso' , 'resuelta' )),
area_id UUID REFERENCES areas(id),
room_id UUID REFERENCES rooms(id),
assigned_to UUID REFERENCES profiles(id),
created_at TIMESTAMP DEFAULT NOW (),
updated_at TIMESTAMP DEFAULT NOW ()
);
Role-Based Access Learn about role-based access control
Real-Time Updates See how incidents update in real-time
Push Notifications Get notified about incident updates
QR Code Scanning Learn about guest authentication