import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../../Notifiers/HomeScreenNotifier.dart'; import '../../Models/hrmModels/advanceListResponse.dart'; import 'package:intl/intl.dart'; import 'package:flutter_svg/svg.dart'; import '../../Notifiers/hrmProvider/advanceProvider.dart'; import '../../Utils/app_colors.dart'; class AdvanceListScreen extends StatefulWidget { const AdvanceListScreen({super.key}); @override State createState() => _AdvanceListScreenState(); } class _AdvanceListScreenState extends State { final ScrollController _scrollController = ScrollController(); @override void initState() { super.initState(); final provider = Provider.of(context, listen: false); final homeProvider = Provider.of(context, listen: false); WidgetsBinding.instance.addPostFrameCallback((_) { provider.fetchAdvanceList(context, homeProvider.session, homeProvider.empId); }); _scrollController.addListener(() { if (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent - 200) { provider.loadMoreAdvanceList(context, homeProvider.session, homeProvider.empId); } }); } @override Widget build(BuildContext context) { final double screenWidth = MediaQuery.of(context).size.width; final double screenHeight = MediaQuery.of(context).size.height; final bool isSmallScreen = screenWidth < 360; final bool isLargeScreen = screenWidth > 600; return Scaffold( appBar: AppBar( automaticallyImplyLeading: false, backgroundColor: Colors.white, title: Row( children: [ InkResponse( onTap: () => Navigator.pop(context, true), child: SvgPicture.asset( "assets/svg/appbar_back_button.svg", height: isSmallScreen ? 22 : 25, ), ), SizedBox(width: isSmallScreen ? 8 : 10), Text( "Advance List", style: TextStyle( fontSize: isSmallScreen ? 16 : 18, fontFamily: "Plus Jakarta Sans", fontWeight: FontWeight.w600, color: Colors.black87, ), ), ], ), ), backgroundColor: AppColors.scaffold_bg_color, body: Consumer( builder: (context, provider, _) { if (provider.isLoading && provider.advanceList.isEmpty) { return const Center(child: CircularProgressIndicator()); } if (provider.errorMessage != null) { return Padding( padding: EdgeInsets.symmetric(horizontal: isSmallScreen ? 16 : 20), child: Center( child: Text( provider.errorMessage!, style: TextStyle( color: Colors.red, fontSize: isSmallScreen ? 14 : 16, fontFamily: "Plus Jakarta Sans", ), textAlign: TextAlign.center, ), ), ); } if (provider.advanceList.isEmpty) { return Padding( padding: EdgeInsets.symmetric(horizontal: isSmallScreen ? 16 : 20), child: Center( child: Text( "No records found.", style: TextStyle( fontSize: isSmallScreen ? 14 : 16, fontFamily: "Plus Jakarta Sans", color: AppColors.grey_semi, ), ), ), ); } return ListView.builder( controller: _scrollController, padding: EdgeInsets.all(isSmallScreen ? 8 : isLargeScreen ? 16 : 12), itemCount: provider.advanceList.length + (provider.isLoading ? 1 : 0), // for pagination loader itemBuilder: (context, index) { if (index == provider.advanceList.length) { return Padding( padding: EdgeInsets.all(isSmallScreen ? 12.0 : 16.0), child: const Center(child: CircularProgressIndicator()), ); } AdvanceList item = provider.advanceList[index]; return _buildAdvanceCard(item, screenWidth); }, ); }, ), ); } Widget _buildAdvanceCard(AdvanceList item, double screenWidth) { final bool isSmallScreen = screenWidth < 360; final bool isLargeScreen = screenWidth > 600; final date = item.createdDatetime != null ? _formatDate(item.createdDatetime!) : "-"; return Card( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(isSmallScreen ? 12 : 16)), margin: EdgeInsets.symmetric( vertical: isSmallScreen ? 5 : 7, horizontal: isLargeScreen ? 4 : 0, ), elevation: 0, child: Padding( padding: EdgeInsets.symmetric( horizontal: isSmallScreen ? 12 : isLargeScreen ? 18 : 14, vertical: isSmallScreen ? 10 : isLargeScreen ? 14 : 12, ), child: Row( children: [ // Circular Avatar - Responsive size CircleAvatar( backgroundColor: _getAvatarColor(item.type), radius: isSmallScreen ? 18 : isLargeScreen ? 26 : 22, child: Text( (item.narration?.isNotEmpty == true) ? item.type![0].toUpperCase() : "?", style: TextStyle( color: _getAvatarTxtColor(item.type), fontWeight: FontWeight.bold, fontSize: isSmallScreen ? 12 : isLargeScreen ? 16 : 14, ), ), ), SizedBox(width: isSmallScreen ? 12 : isLargeScreen ? 16 : 14), // Title + Subtitle Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( item.narration ?? "No Title", style: TextStyle( fontFamily: "JakartaRegular", fontSize: isSmallScreen ? 13 : isLargeScreen ? 16 : 14, color: AppColors.semi_black, ), maxLines: 2, overflow: TextOverflow.ellipsis, ), SizedBox(height: isSmallScreen ? 2 : 4), Text( date, style: TextStyle( fontFamily: "JakartaRegular", fontSize: isSmallScreen ? 12 : isLargeScreen ? 14 : 13, color: AppColors.grey_semi, ), ), ], ), ), SizedBox(width: isSmallScreen ? 8 : isLargeScreen ? 12 : 10), // Right side amounts Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ if (item.issuedAmount != "₹ 0.00") Text( "${item.issuedAmount ?? "0"}", style: TextStyle( fontFamily: "JakartaMedium", fontSize: isSmallScreen ? 13 : isLargeScreen ? 16 : 14, color: const Color(0xff1487c9), ), textAlign: TextAlign.end, ), if (item.deductedAmount != "₹ 0.00") SizedBox(height: isSmallScreen ? 1 : 2), if (item.deductedAmount != "₹ 0.00") Text( "-${item.deductedAmount ?? "0"}", style: TextStyle( fontFamily: "JakartaMedium", fontSize: isSmallScreen ? 13 : isLargeScreen ? 16 : 14, color: AppColors.red, ), textAlign: TextAlign.end, ), ], ), ], ), ), ); } String _formatDate(String dateStr) { try { final date = DateTime.parse(dateStr); return DateFormat("dd MMM yy").format(date); } catch (_) { return dateStr; } } @override void dispose() { _scrollController.dispose(); super.dispose(); } /// Avatar color generator Color _getAvatarColor(value) { var color = AppColors.approved_bg_color; switch (value) { case 'issued': return AppColors.requested_bg_color; case 'received': return AppColors.approved_bg_color; } return color; } Color _getAvatarTxtColor(value) { var color = AppColors.approved_text_color; switch (value) { case 'issued': return AppColors.requested_text_color; case 'received': return AppColors.approved_text_color; } return color; } String getText(value) { switch (value) { case 'issued': return "I"; case 'received': return "R"; default: return "-"; } } }