it0/it0_app/lib/features/billing/presentation/providers/billing_provider.dart

88 lines
2.8 KiB
Dart

import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../../core/network/dio_client.dart';
class LatestInvoice {
final String invoiceNumber;
final String status;
final String currency;
final double amount;
const LatestInvoice({
required this.invoiceNumber,
required this.status,
required this.currency,
required this.amount,
});
factory LatestInvoice.fromJson(Map<String, dynamic> json) => LatestInvoice(
invoiceNumber: json['invoiceNumber'] as String? ?? '',
status: json['status'] as String? ?? '',
currency: json['currency'] as String? ?? 'USD',
amount: (json['totalAmount'] as num?)?.toDouble() ?? 0,
);
}
class BillingOverview {
final String planDisplayName;
final String subscriptionStatus;
final DateTime? currentPeriodEnd;
final DateTime? trialEndsAt;
final int usedTokens;
final int limitTokens;
final bool overageAllowed;
final LatestInvoice? latestInvoice;
const BillingOverview({
required this.planDisplayName,
required this.subscriptionStatus,
required this.currentPeriodEnd,
required this.trialEndsAt,
required this.usedTokens,
required this.limitTokens,
required this.overageAllowed,
required this.latestInvoice,
});
}
final billingOverviewProvider = FutureProvider<BillingOverview>((ref) async {
final dio = ref.read(dioClientProvider);
// Fetch subscription, quota, and recent invoice (ignore 404s gracefully)
Map<String, dynamic>? sub;
Map<String, dynamic>? quota;
Map<String, dynamic>? invoicesData;
try {
final r = await dio.get('/api/v1/billing/subscription');
sub = r.data as Map<String, dynamic>?;
} catch (_) {}
try {
final r = await dio.get('/api/v1/billing/usage/current');
quota = r.data as Map<String, dynamic>?;
} catch (_) {}
try {
final r = await dio.get('/api/v1/billing/invoices?limit=1');
invoicesData = r.data as Map<String, dynamic>?;
} catch (_) {}
final invoices = (invoicesData?['data'] as List?)?.cast<Map<String, dynamic>>() ?? [];
final latestInvoice = invoices.isNotEmpty ? LatestInvoice.fromJson(invoices.first) : null;
return BillingOverview(
planDisplayName: ((sub?['plan'] as Map<String, dynamic>?)?['displayName'] as String?) ?? 'Free',
subscriptionStatus: sub?['status'] as String? ?? 'unknown',
currentPeriodEnd: sub?['currentPeriodEnd'] != null
? DateTime.tryParse(sub!['currentPeriodEnd'] as String)
: null,
trialEndsAt: sub?['trialEndsAt'] != null
? DateTime.tryParse(sub!['trialEndsAt'] as String)
: null,
usedTokens: quota?['usedTokens'] as int? ?? 0,
limitTokens: quota?['limitTokens'] as int? ?? 0,
overageAllowed: quota?['overageAllowed'] as bool? ?? false,
latestInvoice: latestInvoice,
);
});