import 'dart:convert'; import 'package:dotted_border/dotted_border.dart'; import 'package:flutter/material.dart'; import 'package:razorpay_flutter/razorpay_flutter.dart'; import 'package:bookatanker/common/settings.dart'; import 'package:bookatanker/supplier/paymnets/credit_accounts_details.dart'; class CreditAccountsScreen extends StatefulWidget { const CreditAccountsScreen({super.key}); @override State createState() => _CreditAccountsScreenState(); } class _CreditAccountsScreenState extends State { bool isLoading = true; List suppliers = []; Razorpay? _razorpay; Supplier? _currentPaySupplier; @override void initState() { super.initState(); fetchCreditAccounts(); _razorpay = Razorpay(); _razorpay?.on( Razorpay.EVENT_PAYMENT_SUCCESS, _handlePaymentSuccess); _razorpay?.on( Razorpay.EVENT_PAYMENT_ERROR, _handlePaymentError); _razorpay?.on( Razorpay.EVENT_EXTERNAL_WALLET, _handleExternalWallet); } @override void dispose() { _razorpay?.clear(); _razorpay = null; super.dispose(); } // ================= FETCH CREDIT ACCOUNTS ================= Future fetchCreditAccounts() async { try { final response = await AppSettings.getAdvanceTransactionsByCustomer(); final decoded = jsonDecode(response); final List data = decoded["data"] ?? []; final List list = data.map((e) { final status = (e["status"] ?? "").toString().toLowerCase(); final amount = double.tryParse(e["advance_amount"].toString()) ?? 0; double balance = 0; if (status == "approved") balance = amount; if (status == "pending") { balance = -amount; } if (status == "completed") { balance = amount; } if (status == "paid_by_customer") balance = amount; return Supplier( name: e["supplierName"] ?? "Supplier", supplierId:e["supplierId"] ?? "***", monthlyAmount: amount, balance: balance, status: status, raw: e, ); }).toList(); setState(() { suppliers = list; isLoading = false; }); } catch (e) { setState(() => isLoading = false); } } // ================= RAZORPAY ================= void _openRazorpay(Supplier supplier) { _currentPaySupplier = supplier; var options = { 'key': 'rzp_test_1VCCWqEXUHdINz', // 🔑 replace in prod 'amount': (supplier.monthlyAmount * 100).toInt(), 'name': 'Advance Payment', 'description': 'Water Credit Top Up', /*'prefill': { 'contact': AppSettings.userMobile, 'email': AppSettings.userEmail, }*/ }; try { _razorpay?.open(options); } catch (e) { debugPrint("Razorpay error: $e"); } } Future _handlePaymentSuccess( PaymentSuccessResponse response) async { if (_currentPaySupplier == null) return; AppSettings.preLoaderDialog(context); final success = await AppSettings.payAdvance( transactionId: _currentPaySupplier!.raw["transactionId"], payload: { "advance_amount": _currentPaySupplier!.monthlyAmount, "payment_type": "razorpay", "ref_number": response.paymentId, }, ); Navigator.of(context, rootNavigator: true).pop(); if (success) { AppSettings.longSuccessToast("Payment successful"); fetchCreditAccounts(); } else { AppSettings.longFailedToast("Payment failed"); } _currentPaySupplier = null; } void _handlePaymentError( PaymentFailureResponse response) { AppSettings.longFailedToast("Payment failed"); } void _handleExternalWallet( ExternalWalletResponse response) {} // ================= UI ================= @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0XFFFFFFFF), appBar: AppSettings.supplierAppBarWithoutActions( "Credit Accounts", context), body: Padding( padding: const EdgeInsets.all(16), child: isLoading ? const Center(child: CircularProgressIndicator()) : ListView( children: [ _addSupplierCard(), const SizedBox(height: 20), ...suppliers.map(_supplierCard).toList(), ], ), ), ); } Widget _addSupplierCard() { return InkWell( onTap: () {}, child: Row( children: [ DottedBorder( borderType: BorderType.Circle, dashPattern: const [6, 3], color: const Color(0XFF444444), strokeWidth: 1, child: Container( width: 48, height: 48, alignment: Alignment.center, child: Image.asset( 'images/plus.png', width: 24, height: 24, color: const Color(0XFF444444), ), ), ), const SizedBox(width: 12), Text( "Add Supplier", style: fontTextStyle( 12, const Color(0XFF232527), FontWeight.w600), ), ], ), ); } Widget _supplierCard(Supplier supplier) { return GestureDetector( onTap: () { if (supplier.status == "pending" || supplier.status == "paid_by_customer") { return; // 🚫 no navigation } Navigator.push( context, MaterialPageRoute( builder: (_) => CreditAccountsDetails(details: supplier), ), ); }, child: Padding( padding: const EdgeInsets.symmetric(vertical: 10), child: Row( children: [ Container( width: 56, height: 56, decoration: BoxDecoration( color: const Color(0xFFE8F2FF), borderRadius: BorderRadius.circular(28), ), child: ClipRRect( borderRadius: BorderRadius.circular(28), child: Image.asset("images/profile_user.png"), ), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( supplier.supplierId, style: fontTextStyle( 12, const Color(0XFF232527), FontWeight.w600), ), /* RichText( text: TextSpan(children: [ TextSpan( text: "₹${supplier.monthlyAmount.toStringAsFixed(0)} ", style: fontTextStyle( 10, const Color(0xFF515253), FontWeight.w400), ), TextSpan( text: "/month", style: fontTextStyle( 10, const Color(0xFF939495), FontWeight.w400), ), ]), ),*/ // ===== STATUS MESSAGES ===== if (supplier.status == "pending") Padding( padding: const EdgeInsets.only(top: 4), child: InkWell( onTap: () => _openRazorpay(supplier), child: Text( "Please top up", style: fontTextStyle( 10, const Color(0XFFE2483D), FontWeight.w600), ), ), ), if (supplier.status == "paid_by_customer") Padding( padding: const EdgeInsets.only(top: 4), child: Text( "Confirmation needed from supplier", style: fontTextStyle( 10, const Color(0XFF939495), FontWeight.w600), ), ), ], ), ), Text( "₹${AppSettings.formDouble(supplier.balance.toStringAsFixed(2))}", style: fontTextStyle( 16, supplier.balance < 0 ? const Color(0XFFE2483D) : const Color(0XFF0A9E04), FontWeight.w600, ), ), ], ), ), ); } } // ================= MODEL ================= class Supplier { final String name; final double monthlyAmount; final double balance; final String status; final String supplierId; final Map raw; Supplier({ required this.name, required this.monthlyAmount, required this.balance, required this.status, required this.supplierId, required this.raw, }); }