import 'dart:developer'; import 'package:data_channel/data_channel.dart'; import 'package:dio/dio.dart'; import 'package:injectable/injectable.dart'; import '../../../common/api/api_client.dart'; import '../../../common/api/api_failure.dart'; import '../../../common/function/app_function.dart'; import '../../../common/url/api_path.dart'; import '../../../domain/wallet/wallet.dart'; import '../wallet_dtos.dart'; import '../wallet_response.dart'; /// Outlet (§4.4) dan riwayat order (§4.5). @injectable class CustomerRemoteDataProvider { final ApiClient _apiClient; final String _logName = 'CustomerRemoteDataProvider'; CustomerRemoteDataProvider(this._apiClient); Future>> fetchOutlets() => _request( 'fetchOutlets', () => _apiClient.get(ApiPath.outlets, headers: getAuthorizationHeader()), (response) => ((response.data as Map)['data'] as List? ?? []) .map((e) => OutletDto.fromJson(Map.from(e as Map))) .toList(), ); Future> fetchOrders({ required int page, required int limit, }) => _request( 'fetchOrders', () => _apiClient.get( ApiPath.orders, headers: getAuthorizationHeader(), params: {'page': page, 'limit': limit}, ), _parseOrderPage, ); Future> fetchOrderDetail(String id) => _request( 'fetchOrderDetail', () => _apiClient.get( '${ApiPath.orders}/$id', headers: getAuthorizationHeader(), ), (response) => CustomerOrderDto.fromJson(walletDataOf(response)), ); /// `data` bisa berupa list langsung dengan `pagination` di envelope, atau /// objek `{ data, pagination }`. CustomerOrderPageDto _parseOrderPage(Response response) { final body = response.data as Map; final payload = body['data']; final rawItems = payload is Map ? payload['data'] : payload; final rawPagination = payload is Map ? payload['pagination'] : body['pagination']; return CustomerOrderPageDto( items: (rawItems as List? ?? []) .map( (e) => CustomerOrderDto.fromJson(Map.from(e as Map)), ) .toList(), pagination: rawPagination is Map ? WalletPaginationDto.fromJson( Map.from(rawPagination), ) : const WalletPaginationDto(), ); } Future> _request( String name, Future Function() call, T Function(Response response) parse, ) async { try { final response = await call(); final failure = parseWalletFailure(response); if (failure != null) return DC.error(failure); return DC.data(parse(response)); } on ApiFailure catch (e, s) { log(name, name: _logName, error: e, stackTrace: s); return DC.error(WalletFailure.serverError(e)); } } }