Add mobile UX optimization with toggleable deliveries overlay

- Add MobileDeliveriesListOpenNotifier provider for overlay state
- Create MobileMapWithOverlay component with slide-up animation
- Update routes_page.dart for responsive mobile/tablet/desktop layouts
- Mobile: full-screen map with FAB toggle for deliveries list
- Tablet/Desktop: maintain existing split-view layout

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-20 14:58:52 -05:00
parent e8ea9a1903
commit 0fefe80d13
4 changed files with 317 additions and 9 deletions
+65
View File
@@ -17,7 +17,9 @@ import '../components/dark_mode_map.dart';
import '../components/loading_dialog.dart';
import '../components/notes_dialog.dart';
import '../components/photo_capture_dialog.dart';
import '../components/mobile_map_with_overlay.dart';
import '../services/location_permission_service.dart';
import '../utils/breakpoints.dart';
import 'deliveries_page.dart';
import 'settings_page.dart';
@@ -462,6 +464,69 @@ class _RoutesPageState extends ConsumerState<RoutesPage> {
}
return allDeliveriesData.when(
data: (allDeliveries) {
final isMobile = context.isMobile;
// Mobile layout: Show routes list full-screen when no route selected
if (isMobile && _selectedRoute == null) {
return RefreshIndicator(
onRefresh: () async {
// ignore: unused_result
ref.refresh(deliveryRoutesProvider);
// ignore: unused_result
ref.refresh(allDeliveriesProvider);
},
child: CollapsibleRoutesSidebar(
routes: routes,
selectedRoute: null,
onRouteSelected: _selectRoute,
),
);
}
// Mobile layout: full-screen map with overlay when route is selected
if (isMobile && _selectedRoute != null) {
final routeDeliveries = allDeliveries
.where((d) => d.routeFragmentId == _selectedRoute!.id)
.toList();
return RefreshIndicator(
onRefresh: () async {
// ignore: unused_result
ref.refresh(deliveryRoutesProvider);
// ignore: unused_result
ref.refresh(allDeliveriesProvider);
},
child: Stack(
children: [
MobileMapWithOverlay(
deliveries: routeDeliveries,
selectedDelivery: _selectedDelivery,
onDeliverySelected: (delivery) {
setState(() {
_selectedDelivery = delivery;
});
_autoShowNotesIfNeeded(delivery);
},
onDeliveryAction: (delivery, action) {
_handleDeliveryAction(action, delivery, _selectedRoute!.id);
},
),
// Back button to return to routes list
Positioned(
top: 16,
left: 16,
child: FloatingActionButton.small(
onPressed: _backToRoutes,
backgroundColor: Theme.of(context).colorScheme.surface,
child: const Icon(Icons.arrow_back),
),
),
],
),
);
}
// Tablet/Desktop layout: split view with map + sidebar
return RefreshIndicator(
onRefresh: () async {
// ignore: unused_result