ionic-planb-logistic-app-fl.../lib/pages/routes_page.dart
Jean-Philippe Brule 5714fd8443 Implement UI/UX enhancements with collapsible routes sidebar and glassmorphic route cards
Adds new components (CollapsibleRoutesSidebar, GlassmorphicRouteCard) and
internationalization support. Updates deliveries and routes pages with improved
navigation and visual presentation using Material Design 3 principles.

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-15 17:55:18 -05:00

175 lines
5.8 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../models/delivery_route.dart';
import '../providers/providers.dart';
import '../utils/breakpoints.dart';
import '../components/collapsible_routes_sidebar.dart';
import '../components/dark_mode_map.dart';
import 'deliveries_page.dart';
import 'settings_page.dart';
class RoutesPage extends ConsumerWidget {
const RoutesPage({super.key});
void _navigateToDeliveries(BuildContext context, DeliveryRoute route) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => DeliveriesPage(
routeFragmentId: route.id,
routeName: route.name,
),
),
);
}
@override
Widget build(BuildContext context, WidgetRef ref) {
final routesData = ref.watch(deliveryRoutesProvider);
final allDeliveriesData = ref.watch(allDeliveriesProvider);
final userProfile = ref.watch(userProfileProvider);
return Scaffold(
appBar: AppBar(
title: const Text('Delivery Routes'),
elevation: 0,
actions: [
userProfile.when(
data: (profile) => PopupMenuButton<String>(
onSelected: (value) {
if (value == 'settings') {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const SettingsPage(),
),
);
}
},
itemBuilder: (BuildContext context) => [
PopupMenuItem(
value: 'profile',
child: Text(profile?.fullName ?? 'User'),
enabled: false,
),
const PopupMenuDivider(),
const PopupMenuItem(
value: 'settings',
child: Text('Settings'),
),
],
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Center(
child: Text(
profile?.fullName ?? 'User',
style: Theme.of(context).textTheme.titleSmall,
),
),
),
),
loading: () => const Padding(
padding: EdgeInsets.all(16.0),
child: SizedBox(
width: 16,
height: 16,
child: CircularProgressIndicator(strokeWidth: 2),
),
),
error: (error, stackTrace) => const SizedBox(),
),
],
),
body: routesData.when(
data: (routes) {
if (routes.isEmpty) {
return const Center(
child: Text('No routes available'),
);
}
return allDeliveriesData.when(
data: (allDeliveries) {
return RefreshIndicator(
onRefresh: () async {
// ignore: unused_result
ref.refresh(deliveryRoutesProvider);
// ignore: unused_result
ref.refresh(allDeliveriesProvider);
},
child: context.isDesktop
? Row(
children: [
Expanded(
child: DarkModeMapComponent(
deliveries: allDeliveries,
selectedDelivery: null,
onDeliverySelected: null,
),
),
CollapsibleRoutesSidebar(
routes: routes,
selectedRoute: null,
onRouteSelected: (route) {
_navigateToDeliveries(context, route);
},
),
],
)
: Column(
children: [
Expanded(
child: DarkModeMapComponent(
deliveries: allDeliveries,
selectedDelivery: null,
onDeliverySelected: null,
),
),
CollapsibleRoutesSidebar(
routes: routes,
selectedRoute: null,
onRouteSelected: (route) {
_navigateToDeliveries(context, route);
},
),
],
),
);
},
loading: () => const Center(
child: CircularProgressIndicator(),
),
error: (error, stackTrace) => Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Error loading deliveries: $error'),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () => ref.refresh(allDeliveriesProvider),
child: const Text('Retry'),
),
],
),
),
);
},
loading: () => const Center(
child: CircularProgressIndicator(),
),
error: (error, stackTrace) => Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Error: $error'),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () => ref.refresh(deliveryRoutesProvider),
child: const Text('Retry'),
),
],
),
),
),
);
}
}