ionic-planb-logistic-app-fl.../lib/providers/providers.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

150 lines
4.2 KiB
Dart

import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../api/types.dart';
import '../api/client.dart';
import '../api/openapi_config.dart';
import '../services/auth_service.dart';
import '../models/user_profile.dart';
import '../models/delivery_route.dart';
import '../models/delivery.dart';
import '../models/delivery_order.dart';
import '../models/delivery_address.dart';
import '../models/delivery_contact.dart';
final authServiceProvider = Provider<AuthService>((ref) {
return AuthService();
});
final apiClientProvider = Provider<CqrsApiClient>((ref) {
return CqrsApiClient(config: ApiClientConfig.production);
});
final isAuthenticatedProvider = FutureProvider<bool>((ref) async {
final authService = ref.watch(authServiceProvider);
return await authService.isAuthenticated();
});
final userProfileProvider = FutureProvider<UserProfile?>((ref) async {
final authService = ref.watch(authServiceProvider);
final token = await authService.getToken();
if (token == null) return null;
return authService.decodeToken(token);
});
final authTokenProvider = FutureProvider<String?>((ref) async {
final authService = ref.watch(authServiceProvider);
return await authService.getToken();
});
final deliveryRoutesProvider = FutureProvider<List<DeliveryRoute>>((ref) async {
final token = ref.watch(authTokenProvider).valueOrNull;
if (token == null) {
throw Exception('User not authenticated');
}
// Create a new client with auth token
final authClient = CqrsApiClient(
config: ApiClientConfig(
baseUrl: ApiClientConfig.production.baseUrl,
defaultHeaders: {'Authorization': 'Bearer $token'},
),
);
final result = await authClient.executeQuery<List<DeliveryRoute>>(
endpoint: 'simpleDeliveryRouteQueryItems',
query: _EmptyQuery(),
fromJson: (json) {
// API returns data wrapped in object with "data" field
if (json is Map<String, dynamic>) {
final data = json['data'];
if (data is List) {
return (data as List<dynamic>).map((r) => DeliveryRoute.fromJson(r as Map<String, dynamic>)).toList();
}
}
return [];
},
);
return result.whenSuccess((routes) => routes) ?? [];
});
final deliveriesProvider = FutureProvider.family<List<Delivery>, int>((ref, routeFragmentId) async {
final token = ref.watch(authTokenProvider).valueOrNull;
if (token == null) {
throw Exception('User not authenticated');
}
final authClient = CqrsApiClient(
config: ApiClientConfig(
baseUrl: ApiClientConfig.production.baseUrl,
defaultHeaders: {'Authorization': 'Bearer $token'},
),
);
final result = await authClient.executeQuery<List<Delivery>>(
endpoint: 'simpleDeliveriesQueryItems',
query: _DeliveriesQuery(routeFragmentId: routeFragmentId),
fromJson: (json) {
// API returns data wrapped in object with "data" field
if (json is Map<String, dynamic>) {
final data = json['data'];
if (data is List) {
return (data as List<dynamic>).map((d) => Delivery.fromJson(d as Map<String, dynamic>)).toList();
}
}
return [];
},
);
return result.whenSuccess((deliveries) => deliveries) ?? [];
});
/// Provider to get all deliveries from all routes
final allDeliveriesProvider = FutureProvider<List<Delivery>>((ref) async {
final routes = ref.watch(deliveryRoutesProvider).valueOrNull ?? [];
if (routes.isEmpty) {
return [];
}
// Fetch deliveries for all routes
final deliveriesFutures = routes.map((route) {
return ref.watch(deliveriesProvider(route.id)).when(
data: (deliveries) => deliveries,
loading: () => <Delivery>[],
error: (_, __) => <Delivery>[],
);
});
// Combine all deliveries
final allDeliveries = <Delivery>[];
for (final deliveries in deliveriesFutures) {
allDeliveries.addAll(deliveries);
}
return allDeliveries;
});
final languageProvider = StateProvider<String>((ref) {
return 'fr';
});
class _EmptyQuery implements Serializable {
@override
Map<String, Object?> toJson() => {};
}
class _DeliveriesQuery implements Serializable {
final int routeFragmentId;
_DeliveriesQuery({required this.routeFragmentId});
@override
Map<String, Object?> toJson() => {
'params': {
'routeFragmentId': routeFragmentId,
},
};
}