Incidents
Report vehicle breakdowns, traffic jams, accidents, or other issues during a trip.
Incident Types
| Type | Description |
|---|---|
vehicle_breakdown | Bus mechanical failure |
traffic_jam | Severe traffic delay |
accident | Road accident involving the bus |
other | Miscellaneous incident |
Incident Statuses
| Status | Description |
|---|---|
reported | Incident just filed |
resolved | Incident resolved by admin |
Report Incident
POST /driver/bus-tracking/incidents
{
"data": {
"incidentType": "vehicle_breakdown",
"description": "Bus engine overheating, unable to continue.",
"latitude": 12.9716,
"longitude": 77.5946
}
}
Get Incident History
GET /driver/bus-tracking/incidents
{
"data": {
"incidents": [
{
"id": "uuid",
"incidentType": "vehicle_breakdown",
"description": "Bus engine overheating",
"status": "resolved",
"reportedAt": "2024-04-01T08:30:00Z",
"latitude": 12.9716,
"longitude": 77.5946
}
]
}
}
UI — Report Incident
class IncidentReportView extends StatefulWidget {
@override
State<IncidentReportView> createState() => _IncidentReportViewState();
}
class _IncidentReportViewState extends State<IncidentReportView> {
String _type = 'vehicle_breakdown';
String _description = '';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Report Incident')),
body: Form(
child: ListView(
padding: const EdgeInsets.all(16),
children: [
DropdownButtonFormField<String>(
value: _type,
decoration: const InputDecoration(labelText: 'Incident Type'),
items: const [
DropdownMenuItem(value: 'vehicle_breakdown', child: Text('Vehicle Breakdown')),
DropdownMenuItem(value: 'traffic_jam', child: Text('Traffic Jam')),
DropdownMenuItem(value: 'accident', child: Text('Accident')),
DropdownMenuItem(value: 'other', child: Text('Other')),
],
onChanged: (v) => setState(() => _type = v!),
),
const SizedBox(height: 16),
TextFormField(
decoration: const InputDecoration(
labelText: 'Description',
hintText: 'Describe the incident...',
),
maxLines: 4,
onChanged: (v) => _description = v,
),
const SizedBox(height: 24),
ElevatedButton(
onPressed: () => context.read<IncidentsViewModel>().reportIncident(
_type,
_description,
),
style: ElevatedButton.styleFrom(backgroundColor: Colors.red),
child: const Text('REPORT INCIDENT'),
),
],
),
),
);
}
}
UI — Incident History
class IncidentHistoryView extends StatelessWidget {
@override
Widget build(BuildContext context) {
final vm = context.watch<IncidentsViewModel>();
if (vm.isLoading) {
return const Center(child: CircularProgressIndicator());
}
if (vm.incidents.isEmpty) {
return const Center(child: Text('No incidents reported'));
}
return ListView.builder(
itemCount: vm.incidents.length,
itemBuilder: (_, i) {
final incident = vm.incidents[i];
final color = incident.status == 'resolved' ? Colors.green : Colors.red;
return Card(
child: ListTile(
leading: CircleAvatar(
backgroundColor: color.withOpacity(0.1),
child: Icon(
incident.incidentType == 'accident'
? Icons.warning
: Icons.error_outline,
color: color,
),
),
title: Text(incident.incidentType.replaceAll('_', ' ').toUpperCase()),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(incident.description),
const SizedBox(height: 4),
Text(
DateFormat('MMM d, y HH:mm').format(incident.reportedAt),
style: const TextStyle(fontSize: 11, color: Colors.grey),
),
],
),
isThreeLine: true,
trailing: Chip(
label: Text(incident.status.toUpperCase()),
backgroundColor: color.withOpacity(0.1),
labelStyle: TextStyle(color: color, fontSize: 10),
),
),
);
},
);
}
}