Home
Dashboard
The home screen shows:
- Assigned Bus card — bus number and route name
- Today's Trips — list of scheduled trips for the day (pickup and dropoff)
- Live Map — flutter_map showing bus position, trip route, and stop markers
- Draggable Bottom Sheet — trip controls (start/pause/resume/end) slide up over the map
Get Assigned Bus
GET /driver/bus-tracking/get-assigned-bus
{
"data": {
"id": "uuid",
"busNumber": "KA-01-AB-1234",
"routeName": "Route 5 — Whitefield"
}
}
Get Today's Trips
GET /driver/bus-tracking/trips
{
"data": {
"trips": [
{
"id": "uuid",
"busId": "uuid",
"scheduleId": "uuid",
"tripType": "pickup",
"status": "scheduled",
"totalDistanceKm": 12.5,
"date": "2024-04-01"
}
]
}
}
UI — Home Screen
class HomeView extends StatefulWidget {
const HomeView({super.key});
@override
State<HomeView> createState() => _HomeViewState();
}
class _HomeViewState extends State<HomeView> {
final MapController _mapController = MapController();
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
context.read<HomeViewModel>().init();
});
}
@override
Widget build(BuildContext context) {
final vm = context.watch<HomeViewModel>();
return Scaffold(
body: Stack(
children: [
// Live map
FlutterMap(
mapController: _mapController,
options: MapOptions(initialCenter: _defaultLatLng, initialZoom: 15),
children: [
TileLayer(
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
),
// Bus marker
if (vm.currentLocation != null)
MarkerLayer(markers: [
Marker(
point: vm.currentLocation!,
child: const Icon(Icons.directions_bus, color: Colors.blue, size: 32),
),
]),
],
),
// Draggable bottom sheet with trip controls
DraggableScrollableSheet(
initialChildSize: 0.3,
minChildSize: 0.1,
maxChildSize: 0.8,
builder: (_, controller) => TripControlPanel(
scrollController: controller,
trips: vm.dayTrips,
onStartTrip: (id) => vm.startTrip(id),
onEndTrip: (id) => vm.endTrip(id),
),
),
],
),
);
}
}
Trip Control Panel
class TripControlPanel extends StatelessWidget {
@override
Widget build(BuildContext context) {
final vm = context.watch<HomeViewModel>();
return Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
),
child: ListView(
controller: scrollController,
padding: const EdgeInsets.all(16),
children: [
// Bus info
if (vm.assignedBus != null)
BusInfoCard(bus: vm.assignedBus!),
const SizedBox(height: 16),
// Trip cards
...vm.dayTrips.expand((day) => day.trips).map((trip) => TripCard(
trip: trip,
onTap: () => AppNavigator.push(context, '/trip-detail/${trip.id}'),
onStart: () => vm.startTrip(trip.id),
onPause: () => vm.pauseTrip(trip.id),
onResume: () => vm.resumeTrip(trip.id),
onEnd: () => vm.endTrip(trip.id),
)),
],
),
);
}
}