import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:gen_rentals/Screens/HelpScreens/EnquiryScreen.dart'; import 'package:gen_rentals/Screens/HelpScreens/HelpScreen.dart'; import 'package:gen_rentals/Screens/ProductsDetailScreen.dart'; import 'package:gen_rentals/Screens/TransactionsScreen.dart'; import 'package:provider/provider.dart'; import '../Models/DashboardResponse.dart'; import '../Notifier/DashboardProvider.dart'; import 'authScreen/LoginScreen.dart'; class DashboardScreen extends StatefulWidget { final String accId; final String sessionId; const DashboardScreen({super.key, required this.accId, required this.sessionId}); @override State createState() => _DashboardScreenState(); } class _DashboardScreenState extends State { @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { // Only fetch dashboard if accId is valid if (widget.accId.isNotEmpty && widget.accId != "null") { Provider.of(context, listen: false).fetchDashboard(accId: widget.accId, sessionId: widget.sessionId); } else { // If accId is invalid, navigate back to login WidgetsBinding.instance.addPostFrameCallback((_) { Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => LoginScreen()), ); }); } }); } @override Widget build(BuildContext context) { final dashboardProvider = Provider.of(context); final dashboardData = dashboardProvider.dashboardData; double screenWidth = MediaQuery.of(context).size.width; double screenHeight = MediaQuery.of(context).size.height; double bottomPadding = MediaQuery.of(context).padding.bottom; // Add null check at the beginning if (dashboardProvider.isLoading && dashboardData == null) { return Scaffold( body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ CircularProgressIndicator(), SizedBox(height: 20), Text("Loading dashboard..."), ], ), ), ); } return SafeArea( top: false, child: Scaffold( body: Container( color: const Color(0xFFF3F3F3), height: screenHeight, child: SingleChildScrollView( child: Column( children: [ // Top background image section Stack( children: [ // Background image Container( width: double.infinity, decoration: BoxDecoration( gradient: const LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ Colors.white54, Color(0xFFF3F3F3), ], ), ), child: Image.asset( 'assets/images/sky_blue_bg.jpg', width: double.infinity, height: 400, fit: BoxFit.cover, ), ), // Content overlay Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Header with profile Container( width: double.infinity, height: 440, decoration: const BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ Color(0x22FFFFFF), Color(0x33FFFFFF), Color(0x88FFFFFF), Color(0xFFF3F3F3), Color(0xFFF3F3F3), ], ), ), child: Column( children: [ const SizedBox(height: 50), Row( mainAxisAlignment: MainAxisAlignment.end, children: [ // Profile icon Container( width: 50, height: 50, decoration: BoxDecoration( color: Colors.white.withOpacity(0.19), shape: BoxShape.circle, border: Border.all( color: Colors.white.withOpacity(0.5), width: 2, ), ), child: const Icon( Icons.person, color: Colors.white, size: 30, ), ), const SizedBox(width: 20) ], ), Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.start, children: [ Image.asset( 'assets/images/gene_png.png', height: 250, width: 250, ), const Text( "Welcome!", style: TextStyle( fontFamily: "Poppins", color: Colors.black, fontSize: 30, fontWeight: FontWeight.w500, ), ), // Use provider data for name Text( dashboardData?.raname ?? "Loading...", style: const TextStyle( fontFamily: "Poppins", color: Colors.grey, fontSize: 16, fontWeight: FontWeight.w400, ), ), ], ), ], ), ), const SizedBox(height: 10), // Main content section Container( padding: const EdgeInsets.symmetric(horizontal: 16), child: Column( children: [ // Balance Amount Card Container( width: double.infinity, padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ const Text( "Balance Amount", style: TextStyle( fontFamily: "Poppins", color: Color(0xFFF00000), fontSize: 14, fontWeight: FontWeight.w400, ), ), const SizedBox(width: 4), SvgPicture.asset( "assets/svg/continue_ic.svg", color: const Color(0xFFF00000), height: 18, width: 18, ), ], ), const SizedBox(height: 8), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ // Use provider data for balance amount - FIXED NULL CHECK Text( dashboardData?.balanceAmount.toString() ?? "0", style: const TextStyle( fontFamily: "Poppins", color: Colors.black, fontSize: 32, fontWeight: FontWeight.w500, ), ), InkResponse( onTap: () => showPaymentBottomSheet(context), child: Text( "Pay Now", style: TextStyle( fontFamily: "Poppins", color: Color(0xFF008CDE), fontSize: 14, fontWeight: FontWeight.w500, ), ), ), ], ), const SizedBox(height: 12), Text( "*Make sure to pay before you incur any fines.", style: TextStyle( fontFamily: "Poppins", color: Colors.grey.shade500, fontSize: 12, fontWeight: FontWeight.w400, ), ), ], ), ), const SizedBox(height: 20), const SizedBox(height: 20), // Subscribed Orders Container( width: double.infinity, padding: const EdgeInsets.symmetric(horizontal: 2, vertical: 10), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Section Title Text( "Subscribed Orders", style: TextStyle( fontFamily: "Poppins", color: Colors.grey.shade800, fontSize: 18, fontWeight: FontWeight.w600, ), ), const SizedBox(height: 16), // Show loading or products list if (dashboardProvider.isLoading && dashboardData == null) const Center( child: CircularProgressIndicator(), ) else if (dashboardData?.orders == null || dashboardData!.orders!.isEmpty) const Text( "No products subscribed", style: TextStyle( fontFamily: "Poppins", color: Colors.grey, fontSize: 14, ), ) else // List of subscribed products from API Column( children: dashboardData!.orders!.map((product) { return Column( children: [ InkResponse( onTap: () { Navigator.push( context, MaterialPageRoute(builder: (context) => ProductsDetailScreen( sessionId: widget.sessionId, accId: widget.accId, orderId: product.orderid.toString(), )), ); }, child: _buildProductItemFromApi(product), ), const SizedBox(height: 16), ], ); }).toList(), ), ], ), ), // Feature cards grid Container( width: double.infinity, padding: const EdgeInsets.all(2), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Big card - Any Requirements Expanded( flex: 2, child: InkResponse( onTap: () { Navigator.push( context, MaterialPageRoute(builder: (context) => EnquiryScreen() ) ); }, child: Container( padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 8), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), border: Border.all( color: Colors.grey.shade200, width: 1, ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 16), Text( "Any \nRequirements ?", style: TextStyle( fontFamily: "Poppins", color: Color(0xFF008CDE), fontSize: 16, fontWeight: FontWeight.w400, ), ), const SizedBox(height: 6), Text( "Submit your enquiry for requirement", style: TextStyle( fontFamily: "Poppins", color: Colors.grey.shade600, fontSize: 14, ), ), ], ), const SizedBox(height: 20), Row( mainAxisAlignment: MainAxisAlignment.end, children: [ SvgPicture.asset( "assets/svg/requirements.svg", height: 58, width: 58, ), ], ), ], ), ), ), ), const SizedBox(width: 10), // Side cards column Expanded( flex: 2, child: Column( children: [ // Have Complaints card Container( width: double.infinity, padding: const EdgeInsets.all(10), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), border: Border.all( color: Colors.grey.shade200, width: 1, ), ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( flex: 5, child: InkResponse( onTap: () { Navigator.push( context, MaterialPageRoute(builder: (context) => HelpScreen()), ); }, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( flex: 5, child: Text( "Need Help?", style: TextStyle( fontFamily: "Poppins", color: Color(0xFF008CDE), fontSize: 14, fontWeight: FontWeight.w400, ), ), ), Expanded( flex: 2, child: SvgPicture.asset( "assets/svg/have_compaints.svg", height: 35, width: 35, ), ), ], ), const SizedBox(height: 4), Text( "Raise a ticket to resolve your issues.", style: TextStyle( fontFamily: "Poppins", color: Colors.grey.shade600, fontWeight: FontWeight.w400, fontSize: 12, ), ), ], ), ), ), ], ), ), const SizedBox(height: 8), // Know Your Payments card InkResponse( onTap: () { Navigator.push( context, MaterialPageRoute(builder: (context) => TransactionsScreen( sessionId: widget.sessionId, accId: widget.accId, )), ); }, child: Container( width: double.infinity, padding: const EdgeInsets.all(10), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), border: Border.all( color: Colors.grey.shade200, width: 1, ), ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( flex: 5, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( flex: 5, child: Text( "Transactions!", style: TextStyle( fontFamily: "Poppins", color: Color(0xFF008CDE), fontSize: 14, fontWeight: FontWeight.w400, ), ), ), Expanded( flex: 2, child: SvgPicture.asset( "assets/svg/know_pay.svg", height: 35, width: 35, ), ), ], ), const SizedBox(height: 4), Text( "View your all transactions with us.", style: TextStyle( fontFamily: "Poppins", color: Colors.grey.shade600, fontWeight: FontWeight.w400, fontSize: 12, ), ), ], ), ), ], ), ), ), ], ), ), ], ), ), SizedBox(height: 10,), ], ), ), ], ), ], ), ], ), ), ), ), ); } // Helper widget for product item from API data Widget _buildProductItemFromApi(Orders product) { final bool hasPending = product.hasPendingPayment == true; final productList = product.products ?? []; return Container( margin: const EdgeInsets.symmetric(vertical: 6), decoration: BoxDecoration( borderRadius: BorderRadius.circular(15), boxShadow: [ BoxShadow( color: Colors.grey.withOpacity(0.15), blurRadius: 6, offset: const Offset(0, 2), ), ], ), child: Stack( children: [ // ===== Red Strip (Behind Card) ===== if (hasPending) Positioned.fill( top: null, child: Align( alignment: Alignment.bottomCenter, child: Container( height: 45, decoration: const BoxDecoration( color: Color(0xFFFFE2E0), borderRadius: BorderRadius.only( bottomLeft: Radius.circular(15), bottomRight: Radius.circular(15), ), ), child: Row( children: [ const SizedBox(width: 12), const Icon(Icons.info_outline, color: Colors.red, size: 18), const SizedBox(width: 6), Expanded( child: Text( product.pendingPaymentText ?? "Payment Pending. Please Pay before incurring fines.", style: const TextStyle( fontFamily: "Poppins", color: Colors.red, fontSize: 12, fontWeight: FontWeight.w400, ), ), ), const SizedBox(width: 12), ], ), ), ), ), // ===== Main White Card ===== Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(15), ), padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ /// Header Row (image, order id, date, badge) Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ Container( padding: const EdgeInsets.all(14), decoration: BoxDecoration( color: const Color(0xffF2F2F2), borderRadius: BorderRadius.circular(16), ), child: Image.network( product.productImage ?? "", height: 40, width: 40, fit: BoxFit.contain, errorBuilder: (context, error, stack) => Image.asset('assets/images/gene_png.png', height: 40, width: 40), ), ), const SizedBox(width: 8), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "#${product.orderid ?? "0"}", style: const TextStyle( fontFamily: "Poppins", color: Color(0xFF008CDE), fontSize: 16, fontWeight: FontWeight.w500, height: 1.2, ), ), Text( product.rentedDate ?? "Rented date not available", style: TextStyle( fontFamily: "Poppins", color: Colors.grey.shade600, fontSize: 12, ), ), ], ), ], ), // ✅ Gradient expiry badge if (product.expiringText != null && product.expiringText!.isNotEmpty) Container( padding: const EdgeInsets.symmetric( horizontal: 10, vertical: 6), decoration: BoxDecoration( gradient: _getGradientByColor(product.expiringInColor), borderRadius: BorderRadius.circular(8), ), child: Text( product.expiringText!, style: const TextStyle( color: Colors.black87, fontSize: 12, fontWeight: FontWeight.w500, ), ), ), ], ), const SizedBox(height: 6), const Divider(), /// ===== Product List (with +3 More on same line) ===== Builder( builder: (context) { final visibleItems = productList.take(2).toList(); final remaining = productList.length - visibleItems.length; return Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ // Left side → Product list (bulleted) Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ for (int i = 0; i < visibleItems.length; i++) Padding( padding: const EdgeInsets.only(bottom: 4), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(width: 8), const Text( "• ", style: TextStyle(color: Colors.black, fontSize: 16), ), Expanded( child: Text( visibleItems[i], style: const TextStyle( color: Colors.black, fontSize: 16, fontWeight: FontWeight.w400, ), ), ), ], ), ), ], ), ), // Right side → +x More (vertically centered) if (remaining > 0) Padding( padding: const EdgeInsets.only(left: 8, right: 4), child: Align( alignment: Alignment.center, child: Text( "+$remaining More", style: const TextStyle( fontFamily: "Poppins", color: Color(0xFF008CDE), fontSize: 14, fontWeight: FontWeight.w500, ), ), ), ), ], ); }, ), ], ), ), ], ), ); } // Gradient helper LinearGradient _getGradientByColor(String? color) { switch (color) { case "Red": return const LinearGradient( colors: [Color(0xFFFFE0E0), Color(0xFFFFC0C0)], begin: Alignment.topLeft, end: Alignment.bottomRight, ); case "Green": default: return const LinearGradient( colors: [Color(0xFFE9FFDD), Color(0xFFB5FFD1)], begin: Alignment.topLeft, end: Alignment.bottomRight, ); } } // Helper method to get gradient based on color from API // LinearGradient _getGradientByColor(String? color) { // switch (color) { // case "red": // return const LinearGradient( // begin: Alignment.topLeft, // end: Alignment.bottomRight, // colors: [ // Color(0xFFFFDDDD), // Color(0xFFFFB5B5), // ], // ); // case "green": // default: // return const LinearGradient( // begin: Alignment.topLeft, // end: Alignment.bottomRight, // colors: [ // Color(0xFFE9FFDD), // Color(0xFFB5FFD1), // ], // ); // } // } void showPaymentBottomSheet(BuildContext context) { showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (BuildContext context) { return SafeArea( bottom: true, child: Container( decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(24), topRight: Radius.circular(24), ), ), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ // Header - Drag handle Center( child: Container( width: 40, height: 4, decoration: BoxDecoration( color: Colors.grey.shade300, borderRadius: BorderRadius.circular(2), ), ), ), const SizedBox(height: 20), // Pay Amount Section Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "Pay", style: TextStyle( fontSize: 16, fontWeight: FontWeight.w400, color: Color(0xFF777777), ), ), SizedBox(height: 4), Text( "₹4218", style: TextStyle( fontSize: 24, fontWeight: FontWeight.w600, color: Colors.black, ), ), ], ), // Rent Amount Section Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ const Text( "Rent Amount", style: TextStyle( fontSize: 14, fontWeight: FontWeight.w400, color: Color(0xFF777777), ), ), const SizedBox(height: 4), GestureDetector( onTap: () { // Handle view bill details }, child: Text( "View Bill Details", style: TextStyle( fontSize: 14, fontWeight: FontWeight.w500, color: Color(0xFF008CDE), ), ), ), ], ), ], ), const SizedBox(height: 10), const Divider(height: 1, color: Color(0xFFEEEEEE)), const SizedBox(height: 18), // Continue Payment Button SizedBox( width: double.infinity, child: ElevatedButton( onPressed: () { // Handle continue payment }, style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF008CDE), foregroundColor: Colors.white, disabledBackgroundColor: const Color(0xFF266E99), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(30), ), padding: const EdgeInsets.symmetric(vertical: 16), ), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 22), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Text( "Continue Payment", style: TextStyle( color: Color(0xFFFFFFFF), fontSize: 16, ), ), SvgPicture.asset( "assets/svg/continue_ic.svg", color: Color(0xFFFFFFFF), height: 25, width: 25, ), ], ), ), ), ), ], ), ), ), ); }, ); } }