import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:gen_service/Screens/TransactionScreens/BillDetailScreen.dart'; import 'package:gen_service/Screens/TransactionScreens/PaymentDetails.dart'; import 'package:provider/provider.dart'; import '../../Notifiers/TransactionsProvider.dart'; import '../../Utility/AppColors.dart'; class TransactionListScreen extends StatefulWidget { final String accId; final String sessionId; const TransactionListScreen({ required this.accId, required this.sessionId, super.key, }); @override State createState() => _TransactionScreenState(); } class _TransactionScreenState extends State { bool _stretch = true; @override void initState() { super.initState(); Future.microtask(() { Provider.of(context, listen: false) .fetchTransactions(widget.accId, widget.sessionId); }); } @override Widget build(BuildContext context) { final provider = Provider.of(context); final balance = provider.transactionList?.balanceAmount ?? "0"; final balanceType = provider.transactionList?.balanceType ?? "Pending"; final totalCredit = provider.transactionList?.totalCredit ?? "0"; final totalDebit = provider.transactionList?.totalDebit ?? "0"; final transactions = provider.transactionList?.transactions ?? {}; bool isPending = balanceType.toLowerCase() =="pending balance"; return RefreshIndicator.adaptive( color: AppColors.amountText, onRefresh: () async { await Future.delayed(const Duration(milliseconds: 600)); Provider.of(context, listen: false) .fetchTransactions(widget.accId, widget.sessionId); }, child: Scaffold( backgroundColor: AppColors.backgroundRegular, body: CustomScrollView( physics: const BouncingScrollPhysics(), slivers: [ /// Top SliverAppBar (balance card) SliverAppBar( stretch: _stretch, pinned: true, expandedHeight: 245, backgroundColor: AppColors.errorBg, elevation: 0, // Remove shadow leading: Container(), // Remove back button toolbarHeight: 0, // Remove toolbar space collapsedHeight: 0, // Completely collapse to 0 height flexibleSpace: FlexibleSpaceBar( stretchModes: const [StretchMode.zoomBackground], background: Container( decoration: BoxDecoration( gradient: isPending ? AppColors.balanceBarGradientP : AppColors.balanceBarGradientA, ), child: SafeArea( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 20), child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ const SizedBox(height: 20), const Text( "Transactions", style: TextStyle( color: Colors.white, fontSize: 22, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 20), Text( "₹$balance", style: const TextStyle( color: Colors.white, fontSize: 36, fontWeight: FontWeight.w600, ), ), Text( "$balanceType", style: const TextStyle(color: Colors.white70, fontSize: 16), ), const SizedBox(height: 10), if (isPending) ElevatedButton( onPressed: () {}, style: ElevatedButton.styleFrom( backgroundColor: Colors.white, foregroundColor: Colors.deepOrange, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20), ), ), child: const Text("Pay Now"), ), ], ), ), ), ), ), ), /// Summary Row (Paid / Pending) SliverToBoxAdapter( child: Container( color: isPending ? AppColors.errorBg : Color(0xFF4076FF), child: Container( decoration: const BoxDecoration( color: AppColors.backgroundRegular, borderRadius: BorderRadius.only( topLeft: Radius.circular(30), topRight: Radius.circular(30), ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox(height: 4,), // Summary Card Container( margin: const EdgeInsets.all(16), padding: const EdgeInsets.all(14), decoration: BoxDecoration( color: const Color(0xFFD7F0FF), borderRadius: BorderRadius.circular(16), border: Border.all(width: 1.1, color: AppColors.buttonColor), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ _buildSummaryItem("₹$totalCredit", "Bill Paid", Colors.green), Container(height: 30, width: 1, color: Colors.grey.shade300), _buildSummaryItem("₹$totalDebit", "Bill Pending", Colors.red), ], ), ), // Transaction List ListView.builder( shrinkWrap: true, // important for embedding inside SliverToBoxAdapter physics: const NeverScrollableScrollPhysics(), // disable inner scrolling itemCount: transactions.length, itemBuilder: (context, index) { final month = transactions.keys.elementAt(index); final items = transactions[month]!; return Container( color: AppColors.backgroundRegular, padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( month, style: const TextStyle( fontFamily: "Poppins", fontWeight: FontWeight.bold, fontSize: 16, ), ), const SizedBox(height: 8), ...items.map((item) { final type = item.atype ?? "Debit"; final title = item.narration ?? "No details"; final date = item.datetime ?? ""; final id = item.id ?? ""; final amount = type.toLowerCase() == "credit" ? "₹${item.cAmount ?? "0"}" : "₹${item.dAmount ?? "0"}"; return InkResponse( onTap: () { // for credit if (item.atype == "Credit") { showDialog( context: context, builder: (context) => PaymentdetailDialog( sessionId: widget.sessionId, accId: widget.accId, billId: item.billId.toString(), ), ); } else { Navigator.push( context, MaterialPageRoute(builder: (context) => BillDetailScreen( sessionId: widget.sessionId, accId: widget.accId, billId: item.billId.toString()) ) ); } }, child: _buildTransactionItem( type: type, title: title, id: id, date: date, amount: amount, ), ); }).toList(), ], ), ); }, ), ], ), ), ), ) ], ), ), ); } /// Summary Card Item Widget _buildSummaryItem(String value, String label, Color color) { return Row( children: [ CircleAvatar( radius: 20, backgroundColor: Colors.white, child: SvgPicture.asset( label== "Bill Paid" ? "assets/svg/cross_up_arrow.svg" : "assets/svg/cross_down_arrow.svg", height: 18, ), ), SizedBox(width: 6,), Column( children: [ Text( value, style: TextStyle( fontSize: 14, fontWeight: FontWeight.bold, color: color, ), ), const SizedBox(height: 4), Text( label, style: const TextStyle(fontSize: 12, color: Colors.grey), ), ], ), ], ); } /// Transaction Item Widget _buildTransactionItem({ required String type, required String title, required String id, required String date, required String amount, }) { final isCredit = type.toLowerCase() == "credit"; return Container( margin: const EdgeInsets.only(bottom: 10), padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 14), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(14), ), child: Row( children: [ CircleAvatar( radius: 20, backgroundColor: isCredit ? Color(0xFFE7FFE5) : Color(0xffFFEFEF), child: SvgPicture.asset( color: isCredit ? Color(0xff4CAF50) : Color(0xFFF00000), isCredit ? "assets/svg/cross_up_arrow.svg" : "assets/svg/cross_down_arrow.svg", height: 18, ), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Text( "#$id | ", style: const TextStyle( fontFamily: "Poppins", fontSize: 12, fontWeight: FontWeight.w400, color: Colors.grey, ), ), Text( date, style: const TextStyle( fontFamily: "Poppins", fontSize: 12, fontWeight: FontWeight.w400, color: Colors.grey, ), ), ], ), const SizedBox(height: 4), Text( title, maxLines: 2, overflow: TextOverflow.ellipsis, style: const TextStyle( fontFamily: "Poppins", fontSize: 14, fontWeight: FontWeight.normal, color: Colors.black, ), ), ], ), ), const SizedBox(width: 12), Text( amount, style: TextStyle( fontFamily: "Poppins", fontSize: 14, fontWeight: FontWeight.w400, color: isCredit ? Colors.green : Colors.red, ), ), ], ), ); } }