import 'dart:async'; import 'dart:io'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:dio/dio.dart'; import 'package:image_picker/image_picker.dart'; import 'package:flutter_image_compress/flutter_image_compress.dart'; import '../../../core/network/dio_client.dart'; import '../domain/customer.dart'; class CustomersNotifier extends AsyncNotifier> { @override FutureOr> build() async { return _fetchCustomers(); } Future> _fetchCustomers([String? search]) async { try { final response = await DioClient().dio.get( '/customers', queryParameters: search != null && search.isNotEmpty ? {'search': search} : null, ); if (response.statusCode == 200) { final List data = response.data; return data.map((e) => Customer.fromJson(e)).toList(); } return []; } catch (e) { print('Error fetching customers: $e'); return []; } } Future refresh([String? search]) async { state = const AsyncValue.loading(); try { final customers = await _fetchCustomers(search); state = AsyncValue.data(customers); } catch (e, stack) { state = AsyncValue.error(e, stack); } } Future addCustomer(Customer customer, {XFile? photo}) async { try { final response = await DioClient().dio.post( '/customers', data: customer.toJson(), ); if (photo != null && response.data != null) { final customerId = response.data['id']; await _uploadPhoto(customerId, photo); } await refresh(); } catch (e) { if (e is DioException) { throw Exception('Failed to add customer: ${e.response?.statusCode} - ${e.response?.data}'); } throw Exception('Failed to add customer: $e'); } } Future updateCustomer(int id, Customer customer, {XFile? photo}) async { try { await DioClient().dio.put( '/customers/$id', data: customer.toJson(), ); if (photo != null) { await _uploadPhoto(id, photo); } await refresh(); } catch (e) { if (e is DioException) { throw Exception('Failed to update customer: ${e.response?.statusCode} - ${e.response?.data}'); } throw Exception('Failed to update customer: $e'); } } Future _uploadPhoto(int customerId, XFile photo) async { final bytes = await photo.readAsBytes(); final compressedBytes = await FlutterImageCompress.compressWithList( bytes, minWidth: 413, minHeight: 531, quality: 85, ); final formData = FormData.fromMap({ 'file': MultipartFile.fromBytes(compressedBytes, filename: photo.name), }); await DioClient().dio.post( '/customers/$customerId/photo', data: formData, ); } Future deleteCustomer(int id) async { try { await DioClient().dio.delete('/customers/$id'); await refresh(); } catch (e) { throw Exception('Failed to delete customer: $e'); } } } final customersProvider = AsyncNotifierProvider>(() { return CustomersNotifier(); });