Files
Kifi/kifi-app/lib/features/sales/providers/customers_provider.dart

117 lines
3.2 KiB
Dart

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<List<Customer>> {
@override
FutureOr<List<Customer>> build() async {
return _fetchCustomers();
}
Future<List<Customer>> _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<dynamic> data = response.data;
return data.map((e) => Customer.fromJson(e)).toList();
}
return [];
} catch (e) {
print('Error fetching customers: $e');
return [];
}
}
Future<void> 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<void> 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<void> 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<void> _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<void> 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<CustomersNotifier, List<Customer>>(() {
return CustomersNotifier();
});