# API Mock Data Guide If you don't have a backend API ready yet, you can use mock data to test the app. This guide shows you how to create and use mock data. ## Creating Mock Data ### Option 1: Modify RouteApiService Edit `lib/services/api/route_api_service.dart` and replace the API calls with mock data: ```dart import 'package:uuid/uuid.dart'; Future> getDriverRoutes(String driverId) async { // Simulate network delay await Future.delayed(const Duration(seconds: 1)); // Return mock data return [ RouteModel( id: 'RT001', driverId: driverId, driverName: 'John Doe', date: DateTime.now(), status: RouteStatus.notStarted, totalDistance: 45.5, estimatedDuration: 120, vehicleId: 'VH123', stops: [ StopModel( id: 'ST001', customerId: 'C001', customerName: 'Acme Corporation', customerPhone: '+1234567890', location: LocationModel( latitude: 37.7749, longitude: -122.4194, address: '123 Market St, San Francisco, CA 94103', ), type: StopType.pickup, status: StopStatus.pending, scheduledTime: DateTime.now().add(const Duration(hours: 1)), items: ['Package A', 'Package B', 'Package C'], orderNumber: 1, ), StopModel( id: 'ST002', customerId: 'C002', customerName: 'Tech Solutions Inc', customerPhone: '+1234567891', location: LocationModel( latitude: 37.7849, longitude: -122.4094, address: '456 Mission St, San Francisco, CA 94105', ), type: StopType.dropoff, status: StopStatus.pending, scheduledTime: DateTime.now().add(const Duration(hours: 2)), items: ['Package A', 'Package B'], orderNumber: 2, ), StopModel( id: 'ST003', customerId: 'C003', customerName: 'Global Supplies Ltd', customerPhone: '+1234567892', location: LocationModel( latitude: 37.7949, longitude: -122.3994, address: '789 Howard St, San Francisco, CA 94107', ), type: StopType.dropoff, status: StopStatus.pending, scheduledTime: DateTime.now().add(const Duration(hours: 3)), items: ['Package C'], orderNumber: 3, ), ], ), RouteModel( id: 'RT002', driverId: driverId, driverName: 'John Doe', date: DateTime.now().add(const Duration(days: 1)), status: RouteStatus.notStarted, totalDistance: 32.8, estimatedDuration: 90, vehicleId: 'VH123', stops: [ StopModel( id: 'ST004', customerId: 'C004', customerName: 'Downtown Retail', customerPhone: '+1234567893', location: LocationModel( latitude: 37.7649, longitude: -122.4294, address: '321 Broadway, San Francisco, CA 94133', ), type: StopType.pickup, status: StopStatus.pending, scheduledTime: DateTime.now().add(const Duration(days: 1, hours: 1)), items: ['Box 1', 'Box 2'], orderNumber: 1, ), ], ), ]; } Future getRouteById(String routeId) async { await Future.delayed(const Duration(seconds: 1)); final routes = await getDriverRoutes('driver_1'); return routes.firstWhere( (route) => route.id == routeId, orElse: () => routes.first, ); } Future updateRouteStatus(String routeId, RouteStatus status) async { await Future.delayed(const Duration(milliseconds: 500)); // Simulate successful update return true; } Future updateStopStatus( String routeId, String stopId, StopStatus status, { String? signature, String? photo, String? notes, }) async { await Future.delayed(const Duration(milliseconds: 500)); // Simulate successful update return true; } Future reportIssue(String routeId, String stopId, String issue) async { await Future.delayed(const Duration(milliseconds: 500)); // Simulate successful report return true; } ``` ### Option 2: Create a Mock Provider Create a separate mock service that you can easily swap: 1. Create `lib/services/api/mock_route_api_service.dart`: ```dart import 'route_api_service.dart'; import '../../features/routes/data/models/route_model.dart'; import '../../features/routes/data/models/stop_model.dart'; import '../../features/routes/data/models/location_model.dart'; class MockRouteApiService extends RouteApiService { final List _mockRoutes = [ // Add your mock routes here ]; @override Future> getDriverRoutes(String driverId) async { await Future.delayed(const Duration(seconds: 1)); return _mockRoutes; } @override Future getRouteById(String routeId) async { await Future.delayed(const Duration(seconds: 1)); return _mockRoutes.firstWhere( (route) => route.id == routeId, orElse: () => _mockRoutes.first, ); } @override Future updateRouteStatus(String routeId, RouteStatus status) async { await Future.delayed(const Duration(milliseconds: 500)); return true; } @override Future updateStopStatus( String routeId, String stopId, StopStatus status, { String? signature, String? photo, String? notes, }) async { await Future.delayed(const Duration(milliseconds: 500)); return true; } @override Future reportIssue(String routeId, String stopId, String issue) async { await Future.delayed(const Duration(milliseconds: 500)); return true; } } ``` 2. Use it in `main.dart`: ```dart void main() { // Use mock service for development // RouteApiService().initialize(); // Production // In development, the provider will use mock data automatically runApp(const FleetDriverApp()); } ``` ## Mock Data Generator Here's a utility to generate random mock data for testing: ```dart import 'dart:math'; import 'package:uuid/uuid.dart'; class MockDataGenerator { static final _random = Random(); static final _uuid = Uuid(); static final List _customerNames = [ 'Acme Corporation', 'Tech Solutions Inc', 'Global Supplies Ltd', 'Downtown Retail', 'Bay Area Logistics', 'Pacific Trading Co', 'Metro Wholesale', 'Summit Distribution', ]; static final List _addresses = [ '123 Market St, San Francisco, CA', '456 Mission St, San Francisco, CA', '789 Howard St, San Francisco, CA', '321 Broadway, San Francisco, CA', '654 Valencia St, San Francisco, CA', '987 Geary Blvd, San Francisco, CA', ]; static final List _items = [ 'Package A', 'Package B', 'Package C', 'Box 1', 'Box 2', 'Crate 1', 'Pallet A', 'Container X', ]; static RouteModel generateRoute({ required String driverId, int stopCount = 3, }) { final stops = List.generate( stopCount, (index) => generateStop(orderNumber: index + 1), ); return RouteModel( id: 'RT${_random.nextInt(9999).toString().padLeft(4, '0')}', driverId: driverId, driverName: 'Driver ${_random.nextInt(100)}', date: DateTime.now().add(Duration(days: _random.nextInt(7))), status: RouteStatus.values[_random.nextInt(RouteStatus.values.length)], stops: stops, totalDistance: 20.0 + _random.nextDouble() * 80, estimatedDuration: 60 + _random.nextInt(180), vehicleId: 'VH${_random.nextInt(999)}', ); } static StopModel generateStop({required int orderNumber}) { return StopModel( id: _uuid.v4(), customerId: 'C${_random.nextInt(9999)}', customerName: _customerNames[_random.nextInt(_customerNames.length)], customerPhone: '+1${_random.nextInt(999999999).toString().padLeft(9, '0')}', location: LocationModel( latitude: 37.7749 + (_random.nextDouble() - 0.5) * 0.1, longitude: -122.4194 + (_random.nextDouble() - 0.5) * 0.1, address: _addresses[_random.nextInt(_addresses.length)], ), type: _random.nextBool() ? StopType.pickup : StopType.dropoff, status: StopStatus.values[_random.nextInt(StopStatus.values.length)], scheduledTime: DateTime.now().add(Duration(hours: orderNumber)), items: List.generate( 1 + _random.nextInt(4), (_) => _items[_random.nextInt(_items.length)], ), orderNumber: orderNumber, ); } static List generateRoutes({ required String driverId, int count = 5, }) { return List.generate( count, (_) => generateRoute(driverId: driverId), ); } } ``` ### Usage: ```dart // In route_api_service.dart Future> getDriverRoutes(String driverId) async { await Future.delayed(const Duration(seconds: 1)); return MockDataGenerator.generateRoutes(driverId: driverId, count: 5); } ``` ## Testing with Mock Data ### Local Testing 1. Use mock data during development 2. Test all UI states (loading, error, empty, success) 3. Test edge cases (no routes, single route, many routes) ### State Testing Test different route and stop statuses: - Routes: notStarted, inProgress, completed, cancelled - Stops: pending, inProgress, completed, failed ### Example Test Scenarios ```dart // Test empty state Future> getDriverRoutes(String driverId) async { return []; } // Test error state Future> getDriverRoutes(String driverId) async { throw Exception('Network error'); } // Test single route Future> getDriverRoutes(String driverId) async { return [MockDataGenerator.generateRoute(driverId: driverId)]; } // Test many routes Future> getDriverRoutes(String driverId) async { return MockDataGenerator.generateRoutes(driverId: driverId, count: 20); } ``` ## Switching to Real API When your backend is ready: 1. Update API base URL in `lib/core/constants/app_constants.dart`: ```dart static const String baseApiUrl = 'https://your-api-url.com/api'; ``` 2. Remove mock data from `route_api_service.dart` 3. Ensure your API returns data in the expected format (matching the models) 4. Test with real API: ```bash flutter run --dart-define=API_URL=https://your-api-url.com/api ``` ## API Response Format Your backend should return JSON in this format: ### Get Routes Response ```json [ { "id": "RT001", "driverId": "driver_1", "driverName": "John Doe", "date": "2025-10-27T10:00:00Z", "status": "notStarted", "totalDistance": 45.5, "estimatedDuration": 120, "vehicleId": "VH123", "stops": [ { "id": "ST001", "customerId": "C001", "customerName": "Acme Corporation", "customerPhone": "+1234567890", "location": { "latitude": 37.7749, "longitude": -122.4194, "address": "123 Market St, San Francisco, CA" }, "type": "pickup", "status": "pending", "scheduledTime": "2025-10-27T11:00:00Z", "items": ["Package A", "Package B"], "orderNumber": 1 } ] } ] ``` ## Tips for Mock Data 1. **Use realistic data**: Coordinates, addresses, names 2. **Test edge cases**: Empty lists, null values, long strings 3. **Simulate delays**: Add realistic network delays 4. **Test errors**: Simulate network failures and API errors 5. **Use different statuses**: Test all possible states 6. **Generate varied data**: Different route lengths, stop counts 7. **Include optional fields**: Test with and without optional data