import '../../models/contribution_model.dart'; import '../../models/contribution_record_model.dart'; import '../../models/contribution_stats_model.dart'; import '../../../core/network/api_client.dart'; import '../../../core/network/api_endpoints.dart'; import '../../../core/error/exceptions.dart'; import '../../../domain/entities/contribution_record.dart'; abstract class ContributionRemoteDataSource { Future getUserContribution(String accountSequence); Future getContributionRecords( String accountSequence, { ContributionSourceType? sourceType, bool includeExpired = false, int page = 1, int pageSize = 50, }); Future getContributionStats(); } class ContributionRemoteDataSourceImpl implements ContributionRemoteDataSource { final ApiClient client; ContributionRemoteDataSourceImpl({required this.client}); @override Future getUserContribution(String accountSequence) async { try { final response = await client.get(ApiEndpoints.contribution(accountSequence)); return ContributionModel.fromJson(response.data); } catch (e) { throw ServerException(e.toString()); } } @override Future getContributionRecords( String accountSequence, { ContributionSourceType? sourceType, bool includeExpired = false, int page = 1, int pageSize = 50, }) async { try { final queryParams = { 'page': page, 'pageSize': pageSize, 'includeExpired': includeExpired, }; if (sourceType != null) { queryParams['sourceType'] = _sourceTypeToString(sourceType); } final response = await client.get( ApiEndpoints.contributionRecords(accountSequence), queryParameters: queryParams, ); return ContributionRecordsPageModel.fromJson(response.data); } catch (e) { throw ServerException(e.toString()); } } @override Future getContributionStats() async { try { final response = await client.get(ApiEndpoints.contributionStats); return ContributionStatsModel.fromJson(response.data); } catch (e) { throw ServerException(e.toString()); } } String _sourceTypeToString(ContributionSourceType type) { switch (type) { case ContributionSourceType.personal: return 'PERSONAL'; case ContributionSourceType.teamLevel: return 'TEAM_LEVEL'; case ContributionSourceType.teamBonus: return 'TEAM_BONUS'; } } }