import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:dio/dio.dart'; import '../../core/api/api_client.dart'; import '../../shared/models/contract.dart'; // StateNotifier-based list provider (fixes Map equality bug) class ContractListNotifier extends StateNotifier> { ContractListNotifier() : super(const AsyncLoading()) { load(); } Future load({String? filter, String? search, int page = 1}) async { state = const AsyncLoading(); try { final params = {'page': page, 'limit': 20}; if (filter != null && filter != 'all') params['status'] = filter; if (search != null && search.isNotEmpty) params['search'] = search; final resp = await apiDio.get('/contracts', queryParameters: params); state = AsyncData(PagedContracts.fromJson(resp.data)); } catch (e) { state = AsyncError(e, StackTrace.current); } } } final contractListProvider = StateNotifierProvider>( (_) => ContractListNotifier(), ); final contractDetailProvider = FutureProvider.autoDispose.family((ref, id) async { final resp = await apiDio.get('/contracts/$id'); return Contract.fromJson(resp.data); }); Future analyzePdf(String filePath, String fileName) async { final formData = FormData.fromMap({ 'file': await MultipartFile.fromFile(filePath, filename: fileName), }); final resp = await apiDio.post( '/contracts/analyze-pdf', data: formData, options: Options(receiveTimeout: const Duration(seconds: 300)), ); return ContractAnalysis.fromJson(resp.data); } Future createContract(Map data) async { final resp = await apiDio.post('/contracts', data: data); return Contract.fromJson(resp.data); } Future updateContract(int id, Map data) async { final resp = await apiDio.put('/contracts/$id', data: data); return Contract.fromJson(resp.data); } Future uploadContractFile(int id, String filePath, String fileName) async { final formData = FormData.fromMap({ 'file': await MultipartFile.fromFile(filePath, filename: fileName), }); final resp = await apiDio.post('/contracts/$id/file', data: formData); return Contract.fromJson(resp.data); }