116 lines
3.2 KiB
Dart
116 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();
|
|
});
|